@designcrowd/library.brand-page 6.0.6-json-prereq-7 → 6.0.6-undo-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 (134) hide show
  1. package/lib/src/{CreatedOnBrandCrowd-de-de-SPVLPi8n.js → CreatedOnBrandCrowd-de-de-BSFTp6yl.js} +1 -1
  2. package/lib/src/{CreatedOnBrandCrowd-en-us-CvtrCPHd.js → CreatedOnBrandCrowd-en-us-rPQrOY1L.js} +1 -1
  3. package/lib/src/{CreatedOnBrandCrowd-es-es-BSsac7jB.js → CreatedOnBrandCrowd-es-es-awd8-QFa.js} +1 -1
  4. package/lib/src/{CreatedOnBrandCrowd-fr-fr-BauENV2a.js → CreatedOnBrandCrowd-fr-ca-CwJ4J7Ow.js} +1 -1
  5. package/lib/src/{CreatedOnBrandCrowd-fr-ca-BauENV2a.js → CreatedOnBrandCrowd-fr-fr-CwJ4J7Ow.js} +1 -1
  6. package/lib/src/{CreatedOnBrandCrowd-pt-pt-Be0hawmr.js → CreatedOnBrandCrowd-pt-br-BXYfTLlD.js} +1 -1
  7. package/lib/src/{CreatedOnBrandCrowd-pt-br-Be0hawmr.js → CreatedOnBrandCrowd-pt-pt-BXYfTLlD.js} +1 -1
  8. package/lib/src/{CreatedOnDcom-de-de-CTjE2Tmn.js → CreatedOnDcom-de-de-kX6u1lNK.js} +1 -1
  9. package/lib/src/{CreatedOnDcom-en-us-DnZRp5Pg.js → CreatedOnDcom-en-us-Bkq5sgFs.js} +1 -1
  10. package/lib/src/{CreatedOnDcom-es-es-J-9qvjy8.js → CreatedOnDcom-es-es-zCAC9ujj.js} +1 -1
  11. package/lib/src/{CreatedOnDcom-fr-ca-BDNHqm4G.js → CreatedOnDcom-fr-ca-BYz6Wzg5.js} +1 -1
  12. package/lib/src/{CreatedOnDcom-fr-fr-B_2-ceuO.js → CreatedOnDcom-fr-fr-CN-wAaSH.js} +1 -1
  13. package/lib/src/{CreatedOnDcom-pt-br-76lJVrAY.js → CreatedOnDcom-pt-br-BrK4Ngg-.js} +1 -1
  14. package/lib/src/{CreatedOnDcom-pt-pt-TQp3CNcu.js → CreatedOnDcom-pt-pt-AfI_g7xJ.js} +1 -1
  15. package/lib/src/brand-page/models/index.d.ts +26 -34
  16. package/lib/src/brand-page/utils/logo.util.d.ts +14 -0
  17. package/lib/src/brand-page/utils/logo.util.js +19 -0
  18. package/lib/src/brand-page/utils/migration.util.js +0 -11
  19. package/lib/src/brand-page/utils/text.util.d.ts +1 -1
  20. package/lib/src/brand-page/utils/text.util.js +0 -32
  21. package/lib/src/brand-page/utils/vcard.util.js +4 -4
  22. package/lib/src/brand-page/utils/view-model.util.d.ts +0 -1
  23. package/lib/src/brand-page/utils/view-model.util.js +20 -68
  24. package/lib/src/brand-page/view-models.d.ts +3 -3
  25. package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +1 -1
  26. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +1 -1
  27. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +1 -1
  28. package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +1 -1
  29. package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +1 -1
  30. package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +1 -1
  31. package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +1 -1
  32. package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +1 -1
  33. package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +1 -1
  34. package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +1 -1
  35. package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +115 -20
  36. package/lib/src/brand-page-maker/composables/useUndoRedoFlag.d.ts +6 -7
  37. package/lib/src/brand-page-maker/composables/useUndoRedoFlag.js +7 -12
  38. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +1 -1
  39. package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +12 -7
  40. package/lib/src/brand-page-maker/stores/history/history-store.d.ts +6 -0
  41. package/lib/src/brand-page-maker/stores/history/history-store.js +11 -1
  42. package/lib/src/brand-page-maker/utils/index.d.ts +0 -2
  43. package/lib/src/brand-page-maker/utils/index.js +0 -2
  44. package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +5 -19
  45. package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +5 -35
  46. package/lib/src/brand-page-maker/validators/field.validator.js +2 -10
  47. package/lib/src/css/library.brand-page-brandCrowd.min.css +1 -1
  48. package/lib/src/css/library.brand-page-brandPage.min.css +1 -1
  49. package/lib/src/css/library.brand-page-designCom.min.css +1 -1
  50. package/lib/src/css/library.brand-page-preview.min.css +1 -1
  51. package/lib/src/index.d.ts +0 -1
  52. package/lib/src/index.mjs +145 -150
  53. package/lib/src/{lib-Bh9Y5_-x.js → lib-BYFWAvIq.js} +55864 -56119
  54. package/lib/src/lib.js +0 -2
  55. package/lib/src/metadata-builder/builders/reorder-pages-builder.d.ts +13 -0
  56. package/lib/src/metadata-builder/builders/reorder-pages-builder.js +49 -0
  57. package/lib/src/metadata-builder/builders/update-content-text-builder.js +15 -20
  58. package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +3 -5
  59. package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +1 -1
  60. package/lib/src/metadata-builder/helpers/rte.helpers.js +3 -6
  61. package/lib/src/shared/content-settings/components/GenericTextInput.mixin.js +1 -14
  62. package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -1
  63. package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +1 -1
  64. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +1 -1
  65. package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +3 -12
  66. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.d.ts +1 -0
  67. package/lib/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.js +18 -7
  68. package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +1 -1
  69. package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +1 -1
  70. package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +1 -1
  71. package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +1 -1
  72. package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +1 -1
  73. package/lib/src/utils/minify-brand-page-metadata.js +1 -4
  74. package/package.json +1 -1
  75. package/src/brand-page/components/text-wrapper/TextWrapper.vue +6 -17
  76. package/src/brand-page/models/index.ts +26 -35
  77. package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
  78. package/src/brand-page/utils/logo.util.test.ts +54 -1
  79. package/src/brand-page/utils/logo.util.ts +23 -0
  80. package/src/brand-page/utils/migration.util.ts +0 -12
  81. package/src/brand-page/utils/style.util.test.ts +0 -51
  82. package/src/brand-page/utils/text.util.ts +4 -43
  83. package/src/brand-page/utils/vcard.util.ts +4 -6
  84. package/src/brand-page/utils/view-model.util.ts +26 -94
  85. package/src/brand-page/view-models.ts +2 -3
  86. package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +1 -1
  87. package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +123 -22
  88. package/src/brand-page-maker/composables/useUndoRedoFlag.ts +7 -13
  89. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +53 -0
  90. package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +13 -16
  91. package/src/brand-page-maker/stores/history/history-store.test.ts +51 -0
  92. package/src/brand-page-maker/stores/history/history-store.ts +19 -0
  93. package/src/brand-page-maker/utils/index.ts +0 -2
  94. package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +3 -4
  95. package/src/brand-page-maker/utils/rich-text-editor.util.ts +11 -50
  96. package/src/brand-page-maker/validators/field.validator.ts +2 -10
  97. package/src/lib.ts +0 -9
  98. package/src/metadata-builder/builders/reorder-pages-builder.ts +80 -0
  99. package/src/metadata-builder/builders/update-content-text-builder.ts +18 -32
  100. package/src/metadata-builder/builders/update-content-text-style-builder.ts +4 -6
  101. package/src/metadata-builder/helpers/rte.helpers.ts +7 -11
  102. package/src/shared/content-settings/components/GenericTextInput.mixin.ts +1 -17
  103. package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +3 -16
  104. package/src/shared/content-settings/components/text-style-field/TextStyleField.mixin.ts +19 -11
  105. package/src/utils/minify-brand-page-metadata.ts +1 -4
  106. package/lib/src/brand-page/utils/migration/migration-18.d.ts +0 -2
  107. package/lib/src/brand-page/utils/migration/migration-18.js +0 -71
  108. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.d.ts +0 -22
  109. package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.js +0 -22
  110. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.d.ts +0 -14
  111. package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.js +0 -39
  112. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
  113. package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.js +0 -66
  114. package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -33
  115. package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -50
  116. package/lib/src/brand-page-maker/utils/rte-sanitize.util.d.ts +0 -6
  117. package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +0 -158
  118. package/lib/src/brand-page-maker/utils/rte-serializer.d.ts +0 -5
  119. package/lib/src/brand-page-maker/utils/rte-serializer.js +0 -112
  120. package/src/brand-page/utils/migration/migration-18.test.ts +0 -72
  121. package/src/brand-page/utils/migration/migration-18.ts +0 -83
  122. package/src/brand-page/utils/text.util.test.ts +0 -47
  123. package/src/brand-page/utils/view-model.pageid-rte.test.ts +0 -104
  124. package/src/brand-page-maker/__fixtures__/complex-rte.fixture.ts +0 -23
  125. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +0 -52
  126. package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.ts +0 -42
  127. package/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.ts +0 -113
  128. package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +0 -200
  129. package/src/brand-page-maker/utils/rte-render-parity.test.ts +0 -156
  130. package/src/brand-page-maker/utils/rte-render.util.ts +0 -77
  131. package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +0 -158
  132. package/src/brand-page-maker/utils/rte-sanitize.util.ts +0 -195
  133. package/src/brand-page-maker/utils/rte-serializer.ts +0 -172
  134. package/src/brand-page-maker/validators/field.validator.test.ts +0 -55
package/lib/src/lib.js CHANGED
@@ -30,8 +30,6 @@ export { minifyBrandPageMetadata, } from './utils/minify-brand-page-metadata';
30
30
  export * as brandPageUtils from './brand-page/utils';
31
31
  export { getOptimalLogoSize, calculateOptimizedLogoDimensions, applyLogoImageBase64UrlToBrandPageTemplateModel, recalculateLogoContentDimensions, recalculateHeaderLogoSizes, } from './brand-page/utils/logo.util';
32
32
  export { sanitizeRTEHtml } from './brand-page-maker/utils';
33
- // BP-5787: RTE JSON storage boundary helpers (render/normalise/sanitise/extract).
34
- export { renderRteToHtml, toRteJson, isTiptapDocument, sanitizeRteJson, getRteJsonPlainText, } from './brand-page-maker/utils';
35
33
  export { getPageSlugFromPageTitle } from './brand-page-maker/utils/slug.util';
36
34
  // AI-pipeline preview (longclaw per-turn snapshots): web-renderer's
37
35
  // /preview/ai-pipeline render page + manifest server route apply the agent's
@@ -0,0 +1,13 @@
1
+ import type { BrandPageModel } from '../../brand-page/models';
2
+ import { BaseMetadataBuilder, type BuilderResult, type MetadataBuilderRequest } from '../models';
3
+ import type { Logger } from '../logger';
4
+ export interface ReorderPagesPayload {
5
+ pageOrder: string[];
6
+ }
7
+ export declare class ReorderPagesBuilder extends BaseMetadataBuilder<ReorderPagesPayload> {
8
+ constructor(request: MetadataBuilderRequest<ReorderPagesPayload>, logger?: Logger);
9
+ validateAsync(): Promise<{
10
+ errors: string[];
11
+ }>;
12
+ buildAsync(model: BrandPageModel): Promise<BuilderResult>;
13
+ }
@@ -0,0 +1,49 @@
1
+ import { BaseMetadataBuilder, } from '../models';
2
+ export class ReorderPagesBuilder extends BaseMetadataBuilder {
3
+ constructor(request, logger) {
4
+ super(request, logger);
5
+ }
6
+ async validateAsync() {
7
+ const errors = [];
8
+ const payload = this.request.payload;
9
+ if (!payload?.pageOrder?.length) {
10
+ errors.push('page_order is required for reorder_pages');
11
+ }
12
+ return { errors };
13
+ }
14
+ async buildAsync(model) {
15
+ this.log('Build called');
16
+ const validation = await this.validateAsync();
17
+ if (validation.errors.length) {
18
+ return { request: this.request, model, errors: validation.errors };
19
+ }
20
+ const { pageOrder } = this.request.payload;
21
+ // Build pageId → routeId lookup from nav.routes
22
+ const pageIdToRouteId = new Map();
23
+ for (const route of model.nav.routes) {
24
+ pageIdToRouteId.set(route.pageId, route.id);
25
+ }
26
+ // Build new nav.orders from the flat page_order (array of pageIds)
27
+ const newOrders = [];
28
+ const seenRouteIds = new Set();
29
+ for (const pageId of pageOrder) {
30
+ const routeId = pageIdToRouteId.get(pageId);
31
+ if (!routeId)
32
+ continue;
33
+ newOrders.push({ routeId, subRoutes: [] });
34
+ seenRouteIds.add(routeId);
35
+ }
36
+ // Safety: append any routes not mentioned (don't lose pages)
37
+ for (const route of model.nav.routes) {
38
+ const routeId = pageIdToRouteId.get(route.pageId);
39
+ if (routeId && !seenRouteIds.has(routeId)) {
40
+ newOrders.push({ routeId, subRoutes: [] });
41
+ }
42
+ }
43
+ model.nav.orders = newOrders;
44
+ this.log({
45
+ message: `Reordered pages: ${pageOrder.join(', ')}`,
46
+ });
47
+ return { request: this.request, model };
48
+ }
49
+ }
@@ -1,23 +1,6 @@
1
1
  import {} from '../../brand-page/models';
2
2
  import { BaseMetadataBuilder, BUILDER_TYPES, } from '../models';
3
- import { hasRTEContent, replaceTextInRTE, isTiptapDocument, renderRteToHtml, toRteJson, } from '../../brand-page-maker/utils';
4
- /**
5
- * BP-5787 — replace the text of an RTE field while preserving formatting, for
6
- * either storage form. JSON is rendered to HTML, edited via the existing
7
- * HTML-preserving replace, then converted back to JSON; plain/legacy strings
8
- * keep the original behaviour.
9
- */
10
- const updateRteFieldValue = (existing, newText) => {
11
- const wasJson = isTiptapDocument(existing);
12
- const existingHtml = wasJson ? renderRteToHtml(existing) : existing;
13
- if (existingHtml &&
14
- typeof existingHtml === 'string' &&
15
- hasRTEContent(existingHtml)) {
16
- const updatedHtml = replaceTextInRTE(existingHtml, newText);
17
- return wasJson ? toRteJson(updatedHtml) : updatedHtml;
18
- }
19
- return newText;
20
- };
3
+ import { hasRTEContent, replaceTextInRTE } from '../../brand-page-maker/utils';
21
4
  export const buildUpdateTextRequest = (id, payload) => {
22
5
  return {
23
6
  id,
@@ -33,7 +16,11 @@ const updateTextField = (target, fieldName, newText) => {
33
16
  const array = target[arrayName];
34
17
  if (Array.isArray(array) && array[+index]) {
35
18
  const existingText = array[+index][property];
36
- const updatedValue = updateRteFieldValue(existingText, newText);
19
+ const updatedValue = existingText &&
20
+ typeof existingText === 'string' &&
21
+ hasRTEContent(existingText)
22
+ ? replaceTextInRTE(existingText, newText)
23
+ : newText;
37
24
  // Create a new array with the updated item to trigger reactivity
38
25
  const newArray = [...array];
39
26
  newArray[+index] = {
@@ -45,7 +32,15 @@ const updateTextField = (target, fieldName, newText) => {
45
32
  }
46
33
  else {
47
34
  // Simple field
48
- target[fieldName] = updateRteFieldValue(target[fieldName], newText);
35
+ const existingText = target[fieldName];
36
+ if (existingText &&
37
+ typeof existingText === 'string' &&
38
+ hasRTEContent(existingText)) {
39
+ target[fieldName] = replaceTextInRTE(existingText, newText);
40
+ }
41
+ else {
42
+ target[fieldName] = newText;
43
+ }
49
44
  }
50
45
  };
51
46
  export class UpdateContentTextBuilder extends BaseMetadataBuilder {
@@ -35,16 +35,14 @@ const mergeStyles = (currentStyle, stylesToUpdate, textStyleOptions) => {
35
35
  });
36
36
  return merged;
37
37
  };
38
- // BP-5787 — apply a style to RTE text natively. applyStyleToRTEText runs Tiptap
39
- // commands on the doc (string or JSON in) and returns JSON — no HTML round-trip.
40
38
  const updateRTEText = (text, style) => {
41
- if (!hasRTEContent(text)) {
39
+ if (!text || typeof text !== 'string' || !hasRTEContent(text)) {
42
40
  return text;
43
41
  }
44
42
  const { externalEditor } = useExternalRichTextEditor();
45
- const updated = applyStyleToRTEText(externalEditor, text, style);
43
+ const updatedText = applyStyleToRTEText(externalEditor, text, style);
46
44
  externalEditor.destroy();
47
- return updated;
45
+ return updatedText;
48
46
  };
49
47
  const findStyleKey = (target, property) => {
50
48
  // Try exact match first (e.g., 'testimonialsStyle')
@@ -1,6 +1,6 @@
1
1
  import type { TextStyleDeclaration } from '../../brand-page';
2
2
  import type { Editor } from '@tiptap/vue-3';
3
- export declare const applyStyleToRTEText: (externalEditor: Editor, contentText: unknown, newContentStyle: TextStyleDeclaration) => unknown;
3
+ export declare const applyStyleToRTEText: (externalEditor: Editor, contentText: string, newContentStyle: TextStyleDeclaration) => string;
4
4
  /**
5
5
  * Converts a Tiptap JSON document (ProseMirror document model) to an HTML
6
6
  * string using a headless Tiptap Editor instance.
@@ -7,11 +7,7 @@ export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle
7
7
  if (!contentText) {
8
8
  return contentText;
9
9
  }
10
- // BP-5787: operate natively on the Tiptap doc. setContent accepts a JSON
11
- // document or an HTML string; the style is applied via editor commands and
12
- // the result is returned as JSON — no HTML round-trip.
13
- const content = typeof contentText === 'string' &&
14
- contentText.includes(ESCAPED_NEWLINE_CHARACTER)
10
+ const content = contentText.includes(ESCAPED_NEWLINE_CHARACTER)
15
11
  ? getRenderText(contentText)
16
12
  : contentText;
17
13
  externalEditor.commands.setContent(content);
@@ -57,7 +53,8 @@ export const applyStyleToRTEText = (externalEditor, contentText, newContentStyle
57
53
  ? chain.setItalic()
58
54
  : chain.unsetItalic();
59
55
  chain.run();
60
- return externalEditor.getJSON();
56
+ const html = externalEditor.getHTML();
57
+ return html;
61
58
  };
62
59
  /**
63
60
  * Converts a Tiptap JSON document (ProseMirror document model) to an HTML
@@ -144,20 +144,7 @@ export default defineComponent({
144
144
  },
145
145
  },
146
146
  watch: {
147
- value(newVal, oldVal) {
148
- // BP-5787: RTE values are Tiptap JSON objects. The parent (TextItemsField)
149
- // re-clones its items array (cloneDeep) on ANY change — including a sibling
150
- // field's style sync — yielding a NEW object reference with identical text
151
- // content. For objects Vue fires this watcher on reference change, so that
152
- // spurious re-clone would overwrite `_value` and clobber an in-flight edit
153
- // (a mark applied but not yet debounced to the store), silently dropping
154
- // the user's formatting. Strings never hit this (same content = same
155
- // reference = no fire), so mirror that: ignore re-clones whose content is
156
- // unchanged from the previous prop value.
157
- if (this.showRichTextEditor &&
158
- JSON.stringify(newVal) === JSON.stringify(oldVal)) {
159
- return;
160
- }
147
+ value(newVal) {
161
148
  this._value = newVal;
162
149
  if (this.showRichTextEditor) {
163
150
  const textValue = escapeContentText(this._value);
@@ -147,7 +147,7 @@ declare const _default: import("vue").DefineComponent<{}, {
147
147
  content: TContent;
148
148
  }>(payload: P): Promise<void>;
149
149
  _captureTemplateSwitchIfEnabled(): void;
150
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
150
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
151
151
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
152
152
  _navigateToActivePage(activePageId?: string): void;
153
153
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -676,7 +676,7 @@ declare const _default: import("vue").DefineComponent<{}, {
676
676
  content: TContent;
677
677
  }>(payload: P): Promise<void>;
678
678
  _captureTemplateSwitchIfEnabled(): void;
679
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
679
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
680
680
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
681
681
  _navigateToActivePage(activePageId?: string): void;
682
682
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -620,7 +620,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
620
620
  content: TContent;
621
621
  }>(payload: P): Promise<void>;
622
622
  _captureTemplateSwitchIfEnabled(): void;
623
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
623
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
624
624
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
625
625
  _navigateToActivePage(activePageId?: string): void;
626
626
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -8,7 +8,7 @@ import { SIDE_BAR_TAB_NAMES } from '@brand-page-maker/constants';
8
8
  import { ITEM_FIELD_TYPES } from '@brand-page-maker/models';
9
9
  import { useUiPageSettingsStore } from '../../../page-settings/store';
10
10
  import { PAGE_SECTIONS } from '../../../page-settings/models';
11
- import { getPlainTextFromRTE, replaceTextInRTE, RTE_ALLOWED_SECTION_TYPES, isRTEManagedStyleField, isTiptapDocument, renderRteToHtml, toRteJson, } from '@brand-page-maker/utils';
11
+ import { getPlainTextFromRTE, replaceTextInRTE, RTE_ALLOWED_SECTION_TYPES, isRTEManagedStyleField, } from '@brand-page-maker/utils';
12
12
  import { isDefaultContentText } from '@shared/content-settings/utils';
13
13
  import { useUiLogoSettingsStore } from '../../../logo-settings/store';
14
14
  const RTE_DISALLOWED_FIELD_NAMES = ['buttonText'];
@@ -262,17 +262,8 @@ export default defineComponent({
262
262
  },
263
263
  onUseGeneratedText(generatedText) {
264
264
  let formattedText = generatedText;
265
- // BP-5787: preserve the field's formatting when dropping in AI text.
266
- // replaceTextInRTE is HTML-based, so JSON is rendered/parsed around it
267
- // (cold AI path, shared editor); string fields use it directly.
268
- if (this.showRichTextEditor) {
269
- if (isTiptapDocument(this.value)) {
270
- formattedText =
271
- toRteJson(replaceTextInRTE(renderRteToHtml(this.value), generatedText)) ?? generatedText;
272
- }
273
- else if (typeof this.value === 'string') {
274
- formattedText = replaceTextInRTE(this.value, generatedText);
275
- }
265
+ if (this.showRichTextEditor && typeof this.value === 'string') {
266
+ formattedText = replaceTextInRTE(this.value, generatedText);
276
267
  }
277
268
  this.contentSettingsStore.updateItemValue({
278
269
  id: this.id,
@@ -383,6 +383,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
383
383
  onLetterSpacingChange(spacing: string): void;
384
384
  onLineHeightChange(lineHeight: string): void;
385
385
  generateFontFamilySelectorKey(): string;
386
+ syncTextStyleTypeSelection(): void;
386
387
  }, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
387
388
  id: {
388
389
  type: StringConstructor;
@@ -124,13 +124,7 @@ export default defineComponent({
124
124
  this.debounceOnTextSizeChange = debounce(this.onTextSizeChange, TEXT_SIZE_CHANGE_DEBOUNCE_WAIT_IN_MS);
125
125
  this.debounceOnLetterSpacingChange = debounce(this.onLetterSpacingChange, TEXT_SIZE_CHANGE_DEBOUNCE_WAIT_IN_MS);
126
126
  this.debounceOnLineHeightChange = debounce(this.onLineHeightChange, TEXT_SIZE_CHANGE_DEBOUNCE_WAIT_IN_MS);
127
- const value = this.value;
128
- if (value.textStyleType) {
129
- const textStyleTypeOption = this.textStyleTypeOptions.find((x) => x.value === value.textStyleType);
130
- if (textStyleTypeOption) {
131
- textStyleTypeOption.isSelected = true;
132
- }
133
- }
127
+ this.syncTextStyleTypeSelection();
134
128
  },
135
129
  computed: {
136
130
  selectedTextStyle() {
@@ -320,9 +314,26 @@ export default defineComponent({
320
314
  generateFontFamilySelectorKey() {
321
315
  return `fontFamilySelector-${this.id}-${Date.now()}`;
322
316
  },
317
+ // Re-derive the text-style-type selection from the current `value`.
318
+ // Seeded in created() and re-run whenever `value` changes (e.g. undo/redo
319
+ // restores the model) so the dropdown title and `selectedTextStyle`
320
+ // reflect the model rather than a stale local flag. (BP-5811 / BP-5817)
321
+ syncTextStyleTypeSelection() {
322
+ const value = this.value;
323
+ this.textStyleTypeOptions.forEach((option) => {
324
+ // The leading Boolean(...) guard is deliberate — do NOT simplify to
325
+ // `option.value === value?.textStyleType`. The "none" option's value
326
+ // is `undefined`, so that form would SELECT it whenever no style is
327
+ // set, whereas the convention (see emitChange) is all-flags-false
328
+ // when there is no textStyleType.
329
+ option.isSelected =
330
+ Boolean(value?.textStyleType) && option.value === value.textStyleType;
331
+ });
332
+ },
323
333
  },
324
334
  watch: {
325
335
  value() {
336
+ this.syncTextStyleTypeSelection();
326
337
  this.$nextTick(() => {
327
338
  this.fontFamilySelectorKey = this.generateFontFamilySelectorKey();
328
339
  });
@@ -134,7 +134,7 @@ declare const _default: import("vue").DefineComponent<{}, {
134
134
  content: TContent;
135
135
  }>(payload: P): Promise<void>;
136
136
  _captureTemplateSwitchIfEnabled(): void;
137
- applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
137
+ applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
138
138
  _syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
139
139
  _navigateToActivePage(activePageId?: string): void;
140
140
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
@@ -3856,7 +3856,7 @@ declare const _default: import("vue").DefineComponent<{}, {
3856
3856
  content: TContent;
3857
3857
  }>(payload: P): Promise<void>;
3858
3858
  _captureTemplateSwitchIfEnabled(): void;
3859
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
3859
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
3860
3860
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
3861
3861
  _navigateToActivePage(activePageId?: string): void;
3862
3862
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -4425,7 +4425,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
4425
4425
  content: TContent;
4426
4426
  }>(payload: P): Promise<void>;
4427
4427
  _captureTemplateSwitchIfEnabled(): void;
4428
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
4428
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
4429
4429
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
4430
4430
  _navigateToActivePage(activePageId?: string): void;
4431
4431
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -184,7 +184,7 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
184
184
  content: TContent;
185
185
  }>(payload: P): Promise<void>;
186
186
  _captureTemplateSwitchIfEnabled(): void;
187
- applyHistorySnapshot(snapshot: import("../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
187
+ applyHistorySnapshot(snapshot: import("../../brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
188
188
  _syncLogoSettingsFromSnapshot(snapshot: import("../../brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
189
189
  _navigateToActivePage(activePageId?: string): void;
190
190
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("../../brand-page").BrandPageModel): void;
@@ -582,7 +582,7 @@ declare const _default: import("vue").DefineComponent<{}, {
582
582
  content: TContent;
583
583
  }>(payload: P): Promise<void>;
584
584
  _captureTemplateSwitchIfEnabled(): void;
585
- applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
585
+ applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string, logoEditsStr?: string, selectedTemplateId?: string | false): Promise<void>;
586
586
  _syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string): Promise<void>;
587
587
  _navigateToActivePage(activePageId?: string): void;
588
588
  _fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
@@ -1,5 +1,5 @@
1
1
  import { BRAND_PAGE_TYPES, } from '../brand-page/models';
2
- import { hasRTEContent, isTiptapDocument } from '../brand-page-maker/utils';
2
+ import { hasRTEContent } from '../brand-page-maker/utils';
3
3
  import { useExternalRichTextEditor } from '../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
4
4
  import { findAssetKey, resolveLogoData, } from './build-asset-manifest';
5
5
  const BUTTON_TYPES = [
@@ -17,9 +17,6 @@ const BUTTON_TYPES = [
17
17
  'tiktok',
18
18
  ];
19
19
  const convertText = (value, editor) => {
20
- // Already Tiptap JSON (BP-5787 storage) — keep as-is.
21
- if (isTiptapDocument(value))
22
- return value;
23
20
  if (typeof value !== 'string' || !value)
24
21
  return undefined;
25
22
  if (hasRTEContent(value)) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@designcrowd/library.brand-page",
3
3
  "description": "A collection of Maker/Designer applications",
4
- "version": "6.0.6-json-prereq-7",
4
+ "version": "6.0.6-undo-2",
5
5
  "author": "Design.com Eng",
6
6
  "license": "UNLICENSED",
7
7
  "type": "module",
@@ -16,13 +16,7 @@
16
16
  </div>
17
17
  </template>
18
18
  <script setup lang="ts">
19
- import {
20
- hasRTEContent,
21
- getPlainTextFromRTE,
22
- renderRteToHtml,
23
- isTiptapDocument,
24
- type RichTextValue,
25
- } from '@brand-page-maker/utils';
19
+ import { hasRTEContent, getPlainTextFromRTE } from '@brand-page-maker/utils';
26
20
  import {
27
21
  type FluidTextData,
28
22
  type TextStyleDeclaration,
@@ -38,8 +32,7 @@ import {
38
32
 
39
33
  interface Props {
40
34
  textStyle: TextStyleDeclaration | undefined;
41
- // BP-5787: an RTE field is a legacy inline-HTML string or a Tiptap JSON doc.
42
- text: RichTextValue;
35
+ text: string;
43
36
  element?: string;
44
37
  slug?: string;
45
38
  }
@@ -81,20 +74,16 @@ const textStyleRTE = computed(() => {
81
74
  };
82
75
  });
83
76
 
84
- // Render either form (legacy HTML string or Tiptap JSON) to final HTML.
85
- // For a string this returns it unchanged, so the legacy path is unaffected.
86
- const renderedHtml = computed(() => renderRteToHtml(props.text));
87
-
88
77
  const isRTEContent = computed(() => {
89
- return isTiptapDocument(props.text) || hasRTEContent(renderedHtml.value);
78
+ return hasRTEContent(props.text);
90
79
  });
91
80
 
92
81
  const sanitizeText = computed(() => {
93
- if (isRTEContent.value && !getPlainTextFromRTE(renderedHtml.value)) {
82
+ if (isRTEContent.value && !getPlainTextFromRTE(props.text)) {
94
83
  return '';
95
84
  }
96
85
 
97
- return renderedHtml.value;
86
+ return props.text;
98
87
  });
99
88
 
100
89
  const fontSize = computed<any>(() => props.textStyle.fontSize);
@@ -166,7 +155,7 @@ const applyScale = () => {
166
155
  }
167
156
 
168
157
  const fontSizeMatchInRTEText = [
169
- ...renderedHtml.value.matchAll(
158
+ ...props.text.matchAll(
170
159
  /style="(?:[^"]*?)\bfont-size\s*:\s*(?<fontSize>[^;"']+)[^"]*?"/gm,
171
160
  ),
172
161
  ].map((x) => parseFloat(x.groups?.fontSize || '1em'));
@@ -29,15 +29,6 @@ import { EMPTY_LOGO_IMAGE_MODEL, LogoStyles } from './logo.model';
29
29
  import type { LogoImageModel, LogoTemplateImageModel } from './logo.model';
30
30
  import cloneDeep from 'lodash.clonedeep';
31
31
  import type { BrandPagePaymentConfig } from './payment.model';
32
- import type { JSONContent } from '@tiptap/vue-3';
33
-
34
- /**
35
- * BP-5787 — a rich-text field is either a legacy inline-HTML string or a
36
- * Tiptap JSON document. Typing RTE content fields as RichTextValue (instead of
37
- * `string`) forces every consumer to handle both forms — surfacing at compile
38
- * time any code that assumes a plain string (e.g. `.replace`, `.length`).
39
- */
40
- export type RichTextValue = string | JSONContent;
41
32
 
42
33
  export * from './brand-page-context.model';
43
34
  export * from './payment.model';
@@ -281,7 +272,7 @@ export interface TextContent extends Content {
281
272
  /**
282
273
  * For BrandPage/BrandContact only
283
274
  */
284
- text: RichTextValue;
275
+ text: string;
285
276
  /**
286
277
  * For BrandSite
287
278
  */
@@ -305,9 +296,9 @@ export interface TextContent extends Content {
305
296
 
306
297
  export interface ProfileContent extends Content {
307
298
  avatarImageUrl: string;
308
- name: RichTextValue;
309
- title: RichTextValue;
310
- description: RichTextValue;
299
+ name: string;
300
+ title: string;
301
+ description: string;
311
302
  backgroundColor: BrandPageCssStyle;
312
303
  colorReplacements: ColorReplacement[];
313
304
  mediaType?: string;
@@ -328,7 +319,7 @@ export interface MapContent extends Content {
328
319
 
329
320
  export interface MailingListContent extends Content {
330
321
  acceptedFields?: 'emailOnly' | 'nameAndEmail';
331
- title: RichTextValue;
322
+ title: string;
332
323
  buttonText: string;
333
324
  titleStyle: TextStyleDeclaration;
334
325
  buttonTextStyle: TextStyleDeclaration;
@@ -387,10 +378,10 @@ export interface FormField {
387
378
  export interface ContactFormContent extends Content {
388
379
  type: 'contact-form';
389
380
  displayStyle: string;
390
- title: RichTextValue;
391
- description: RichTextValue;
381
+ title: string;
382
+ description: string;
392
383
  buttonText: string;
393
- successMessage: RichTextValue;
384
+ successMessage: string;
394
385
  fields: FormField[];
395
386
  responseEmail: string;
396
387
  imageUrl?: string;
@@ -410,8 +401,8 @@ export interface ContactFormContent extends Content {
410
401
  export interface BannerSectionContent extends Content {
411
402
  type: 'banner-section';
412
403
  imageUrl: string;
413
- title: RichTextValue;
414
- description: RichTextValue;
404
+ title: string;
405
+ description: string;
415
406
  buttonText: string | false;
416
407
  url: string;
417
408
  email?: string;
@@ -441,8 +432,8 @@ export const MEDIA_TYPES = {
441
432
  export type MediaType = keyof typeof MEDIA_TYPES;
442
433
 
443
434
  export interface TextMediaItem extends ImageItem {
444
- title: RichTextValue;
445
- paragraph: RichTextValue;
435
+ title: string;
436
+ paragraph: string;
446
437
  itemsId: number;
447
438
 
448
439
  buttonText?: string | false;
@@ -466,8 +457,8 @@ export interface TextShapeItem extends TextMediaItem {
466
457
  export interface ShapeItem extends ImageItem {
467
458
  colorReplacements: ColorReplacement[];
468
459
  mediaType: MediaType;
469
- title?: RichTextValue;
470
- paragraph?: RichTextValue;
460
+ title?: string;
461
+ paragraph?: string;
471
462
 
472
463
  // overrides for personalisation
473
464
  titleOverride?: string;
@@ -476,9 +467,9 @@ export interface ShapeItem extends ImageItem {
476
467
 
477
468
  export interface TestimonialItems {
478
469
  imageUrl: string;
479
- name: RichTextValue;
480
- position: RichTextValue;
481
- testimonials: RichTextValue;
470
+ name: string;
471
+ position: string;
472
+ testimonials: string;
482
473
  colorReplacements: ColorReplacement[];
483
474
  mediaType: string;
484
475
  size?: string;
@@ -492,7 +483,7 @@ export interface TestimonialItems {
492
483
  }
493
484
 
494
485
  export interface TextItem {
495
- text: RichTextValue;
486
+ text: string;
496
487
  textStyle: TextStyleDeclaration;
497
488
 
498
489
  // overrides for personalisation
@@ -514,8 +505,8 @@ export interface ImagesSectionContent extends Content, MediaSection {
514
505
  }
515
506
 
516
507
  export interface MediaSection extends Content {
517
- title: RichTextValue;
518
- description: RichTextValue;
508
+ title: string;
509
+ description: string;
519
510
  displayStyle: ImagesSectionContentDisplayStyle;
520
511
  items: TextShapeItem[] | TextMediaItem[];
521
512
  titleStyle: TextStyleDeclaration;
@@ -534,7 +525,7 @@ export interface ColorReplacement {
534
525
 
535
526
  export interface TestimonialSectionContent extends Content {
536
527
  type: 'testimonial-section';
537
- title: RichTextValue;
528
+ title: string;
538
529
  displayStyle: string;
539
530
  items: TestimonialItems[];
540
531
  titleStyle: TextStyleDeclaration;
@@ -549,8 +540,8 @@ export interface TestimonialSectionContent extends Content {
549
540
  export interface AboutSectionContent extends Content {
550
541
  type: 'about-section';
551
542
  imageUrl: string;
552
- title: RichTextValue;
553
- paragraph: RichTextValue;
543
+ title: string;
544
+ paragraph: string;
554
545
  displayStyle: string;
555
546
  titleStyle: TextStyleDeclaration;
556
547
  paragraphStyle: TextStyleDeclaration;
@@ -577,7 +568,7 @@ export type SocialLinksIconDisplayStyle =
577
568
 
578
569
  export interface SocialLinksContent extends Content {
579
570
  type: 'social-links';
580
- title: RichTextValue;
571
+ title: string;
581
572
  links: LinksItem[];
582
573
  iconDisplayStyle: SocialLinksIconDisplayStyle;
583
574
  iconFillStyles: BrandPageCssStyle;
@@ -604,8 +595,8 @@ export interface DividerSectionContent extends Content {
604
595
 
605
596
  export interface BookingSectionContent extends Content {
606
597
  type: 'booking-section';
607
- title: RichTextValue;
608
- description: RichTextValue;
598
+ title: string;
599
+ description: string;
609
600
  buttonText: string;
610
601
  url: string;
611
602
  email?: string;
@@ -457,7 +457,7 @@ exports[`migration.util > Banner Contents - text Align and Font Family should no
457
457
  },
458
458
  },
459
459
  "userPromptContentKey": undefined,
460
- "v": 18,
460
+ "v": 17,
461
461
  },
462
462
  "useOldLogoRenderSize": true,
463
463
  }
@@ -903,7 +903,7 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
903
903
  },
904
904
  },
905
905
  "userPromptContentKey": undefined,
906
- "v": 18,
906
+ "v": 17,
907
907
  },
908
908
  "useOldLogoRenderSize": true,
909
909
  }
@@ -1356,7 +1356,7 @@ exports[`migration.util > migrateBrandPageModel should return brand page model w
1356
1356
  },
1357
1357
  },
1358
1358
  "userPromptContentKey": undefined,
1359
- "v": 18,
1359
+ "v": 17,
1360
1360
  },
1361
1361
  "useOldLogoRenderSize": true,
1362
1362
  }