@designcrowd/library.brand-page 6.0.26-json-prereq-2 → 6.0.27-websitev2-dev-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/src/{CreatedOnBrandCrowd-de-de-CKBqjDH3.js → CreatedOnBrandCrowd-de-de-BpFKOKIo.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-CRXiimvT.js → CreatedOnBrandCrowd-en-us-USGAnC_n.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-DCYdY6sj.js → CreatedOnBrandCrowd-es-es-CvVx3h4H.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-Dk7LOhxE.js → CreatedOnBrandCrowd-fr-ca-BCwamW5a.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-Dk7LOhxE.js → CreatedOnBrandCrowd-fr-fr-BCwamW5a.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-Cp4ufHJP.js → CreatedOnBrandCrowd-pt-br-Bt72hMrQ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-Cp4ufHJP.js → CreatedOnBrandCrowd-pt-pt-Bt72hMrQ.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-ZSLkWMwM.js → CreatedOnDcom-de-de-BxUDrgG9.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-BgdIGfT3.js → CreatedOnDcom-en-us-wjVp5eOs.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-D0KemkCZ.js → CreatedOnDcom-es-es-CwFL2q5h.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-BuwNjNbC.js → CreatedOnDcom-fr-ca-BPZ2_PNq.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-DCQcsFPf.js → CreatedOnDcom-fr-fr-D0vLOikZ.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-DD-oLAS1.js → CreatedOnDcom-pt-br-CTwbxm9H.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-D8qLq2wW.js → CreatedOnDcom-pt-pt-Cfqf8LaM.js} +1 -1
- package/lib/src/brand-page/components/contact-form/ContactForm.mixin.js +2 -5
- package/lib/src/brand-page/models/index.d.ts +26 -34
- package/lib/src/brand-page/utils/migration.util.js +0 -11
- package/lib/src/brand-page/utils/text.util.d.ts +1 -1
- package/lib/src/brand-page/utils/text.util.js +0 -32
- package/lib/src/brand-page/utils/vcard.util.js +4 -4
- package/lib/src/brand-page/utils/view-model.util.d.ts +0 -1
- package/lib/src/brand-page/utils/view-model.util.js +20 -68
- package/lib/src/brand-page/view-models.d.ts +3 -3
- package/lib/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.d.ts +1 -0
- package/lib/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.js +7 -3
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.d.ts +9 -2
- package/lib/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.js +10 -6
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.d.ts +20 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.js +44 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.d.ts +27 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.js +44 -0
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.d.ts +1 -1
- package/lib/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.js +103 -24
- package/lib/src/brand-page-maker/utils/index.d.ts +0 -2
- package/lib/src/brand-page-maker/utils/index.js +0 -2
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +5 -28
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +5 -48
- package/lib/src/brand-page-maker/validators/field.validator.js +2 -10
- package/lib/src/clients/ai-assistant-client.d.ts +1 -0
- package/lib/src/clients/ai-assistant-client.js +1 -0
- package/lib/src/css/library.brand-page-brandCrowd.min.css +39 -39
- package/lib/src/css/library.brand-page-brandPage.min.css +39 -39
- package/lib/src/css/library.brand-page-designCom.min.css +39 -39
- package/lib/src/css/library.brand-page-preview.min.css +39 -39
- package/lib/src/index.d.ts +0 -1
- package/lib/src/index.mjs +138 -143
- package/lib/src/{lib-Db6j9fQZ.js → lib-Cg4BExY4.js} +72135 -75458
- package/lib/src/lib.js +0 -2
- package/lib/src/metadata-builder/ai-metadata-executor.d.ts +1 -0
- package/lib/src/metadata-builder/ai-metadata-executor.js +19 -0
- package/lib/src/metadata-builder/builders/global-font-propagation.d.ts +28 -0
- package/lib/src/metadata-builder/builders/global-font-propagation.js +125 -0
- package/lib/src/metadata-builder/builders/global-styles-builder.js +16 -0
- package/lib/src/metadata-builder/builders/section-builders/about-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/banner-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/booking-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/contact-form-builder.js +4 -3
- package/lib/src/metadata-builder/builders/section-builders/images-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/index.d.ts +1 -0
- package/lib/src/metadata-builder/builders/section-builders/index.js +1 -0
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-builder.js +2 -1
- package/lib/src/metadata-builder/builders/section-builders/mailing-list-section-builder.js +2 -1
- package/lib/src/metadata-builder/builders/section-builders/profile-section-builder.js +4 -3
- package/lib/src/metadata-builder/builders/section-builders/shapes-section-builder.js +3 -2
- package/lib/src/metadata-builder/builders/section-builders/support-me-builder.d.ts +8 -0
- package/lib/src/metadata-builder/builders/section-builders/support-me-builder.js +25 -0
- package/lib/src/metadata-builder/builders/section-builders/testimonial-section-builder.js +2 -1
- package/lib/src/metadata-builder/builders/section-builders/text-section-builder.js +16 -17
- package/lib/src/metadata-builder/builders/section-field-maps.js +15 -0
- package/lib/src/metadata-builder/builders/section-field-utils.d.ts +6 -1
- package/lib/src/metadata-builder/builders/section-field-utils.js +48 -12
- package/lib/src/metadata-builder/builders/section-rules/support-me.rules.d.ts +2 -0
- package/lib/src/metadata-builder/builders/section-rules/support-me.rules.js +17 -0
- package/lib/src/metadata-builder/builders/update-content-text-builder.d.ts +17 -0
- package/lib/src/metadata-builder/builders/update-content-text-builder.js +103 -0
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.d.ts +16 -0
- package/lib/src/metadata-builder/builders/update-content-text-style-builder.js +216 -0
- package/lib/src/metadata-builder/helpers/rte.helpers.d.ts +13 -11
- package/lib/src/metadata-builder/helpers/rte.helpers.js +73 -14
- package/lib/src/metadata-builder/metadata-executor.js +7 -1
- package/lib/src/metadata-builder/models.d.ts +4 -0
- package/lib/src/metadata-builder/models.js +4 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.d.ts +20 -0
- package/lib/src/metadata-builder/parsers/ai-toolcall-parser.js +8 -0
- package/lib/src/metadata-builder/parsers/section-tool-arguments.d.ts +14 -2
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.d.ts +8 -7
- package/lib/src/metadata-builder/sanitizers/rte-schema-check.js +52 -21
- package/lib/src/shared/content-settings/components/GenericTextInput.mixin.js +1 -14
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +3 -12
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +2 -3
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +3 -10
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +1 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +1 -4
- package/lib/src/utils/minify-brand-page-metadata.js +8 -4
- package/package.json +15 -17
- package/src/brand-page/components/contact-form/ContactForm.mixin.ts +2 -5
- package/src/brand-page/components/text-wrapper/TextWrapper.vue +6 -17
- package/src/brand-page/models/index.ts +26 -35
- package/src/brand-page/utils/__snapshots__/migration.util.test.ts.snap +3 -3
- package/src/brand-page/utils/migration.util.ts +0 -12
- package/src/brand-page/utils/style.util.test.ts +0 -51
- package/src/brand-page/utils/text.util.ts +4 -43
- package/src/brand-page/utils/vcard.util.ts +4 -6
- package/src/brand-page/utils/view-model.util.ts +26 -94
- package/src/brand-page/view-models.ts +2 -3
- package/src/brand-page-maker/components/ai-website-builder/AiWebsiteBuilder.vue +1 -1
- package/src/brand-page-maker/components/rich-text-editor/RichTextEditor.vue +3 -4
- package/src/brand-page-maker/composables/ai-chat/useAiMetadataBuilder.ts +1 -0
- package/src/brand-page-maker/composables/ai-chat/useAiWebsiteBuilderChat.ts +7 -3
- package/src/brand-page-maker/composables/rich-text-editor/bubbleMenu.ts +10 -6
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontSize.ts +73 -0
- package/src/brand-page-maker/composables/rich-text-editor/extensions/LineHeight.ts +85 -0
- package/src/brand-page-maker/composables/rich-text-editor/useRichTextEditor.ts +111 -27
- package/src/brand-page-maker/utils/index.ts +0 -2
- package/src/brand-page-maker/utils/rich-text-editor.util.test.ts +3 -37
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +11 -66
- package/src/brand-page-maker/validators/field.validator.ts +2 -10
- package/src/clients/ai-assistant-client.ts +1 -0
- package/src/lib.ts +0 -9
- package/src/metadata-builder/ai-metadata-executor.ts +26 -0
- package/src/metadata-builder/builders/global-font-propagation.test.ts +269 -0
- package/src/metadata-builder/builders/global-font-propagation.ts +205 -0
- package/src/metadata-builder/builders/global-styles-builder.ts +21 -0
- package/src/metadata-builder/builders/section-builders/about-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/banner-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/booking-section-builder.ts +5 -2
- package/src/metadata-builder/builders/section-builders/contact-form-builder.ts +4 -3
- package/src/metadata-builder/builders/section-builders/images-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/index.ts +1 -0
- package/src/metadata-builder/builders/section-builders/mailing-list-builder.ts +2 -1
- package/src/metadata-builder/builders/section-builders/mailing-list-section-builder.ts +2 -1
- package/src/metadata-builder/builders/section-builders/profile-section-builder.ts +6 -3
- package/src/metadata-builder/builders/section-builders/shapes-section-builder.ts +3 -2
- package/src/metadata-builder/builders/section-builders/support-me-builder.test.ts +177 -0
- package/src/metadata-builder/builders/section-builders/support-me-builder.ts +43 -0
- package/src/metadata-builder/builders/section-builders/testimonial-section-builder.ts +2 -1
- package/src/metadata-builder/builders/section-builders/text-section-builder.ts +18 -21
- package/src/metadata-builder/builders/section-field-maps.ts +18 -0
- package/src/metadata-builder/builders/section-field-utils.test.ts +83 -0
- package/src/metadata-builder/builders/section-field-utils.ts +69 -18
- package/src/metadata-builder/builders/section-rules/support-me.rules.ts +39 -0
- package/src/metadata-builder/builders/update-content-text-builder.ts +148 -0
- package/src/metadata-builder/builders/update-content-text-style-builder.ts +352 -0
- package/src/metadata-builder/helpers/rte.helpers.ts +101 -15
- package/src/metadata-builder/metadata-executor.ts +8 -0
- package/src/metadata-builder/models.ts +5 -0
- package/src/metadata-builder/parsers/ai-toolcall-parser.ts +31 -0
- package/src/metadata-builder/parsers/section-tool-arguments.ts +14 -1
- package/src/metadata-builder/sanitizers/rte-schema-check.ts +53 -24
- package/src/shared/content-settings/components/GenericTextInput.mixin.ts +1 -17
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +3 -16
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +4 -13
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +4 -6
- package/src/shared/content-settings/components/text-image-field/TextImageField.vue +3 -6
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +1 -6
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +1 -1
- package/src/utils/minify-brand-page-metadata.test.ts +61 -0
- package/src/utils/minify-brand-page-metadata.ts +9 -4
- package/lib/src/brand-page/utils/migration/migration-20.d.ts +0 -2
- package/lib/src/brand-page/utils/migration/migration-20.js +0 -66
- package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.d.ts +0 -22
- package/lib/src/brand-page-maker/__fixtures__/complex-rte.fixture.js +0 -22
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.d.ts +0 -14
- package/lib/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.js +0 -39
- package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.d.ts +0 -28
- package/lib/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.js +0 -90
- package/lib/src/brand-page-maker/utils/rte-render.util.d.ts +0 -63
- package/lib/src/brand-page-maker/utils/rte-render.util.js +0 -95
- package/lib/src/brand-page-maker/utils/rte-sanitize.util.d.ts +0 -6
- package/lib/src/brand-page-maker/utils/rte-sanitize.util.js +0 -158
- package/src/brand-page/utils/migration/migration-20.server.test.ts +0 -125
- package/src/brand-page/utils/migration/migration-20.test.ts +0 -72
- package/src/brand-page/utils/migration/migration-20.ts +0 -87
- package/src/brand-page/utils/text.util.test.ts +0 -47
- package/src/brand-page/utils/view-model.pageid-rte.test.ts +0 -104
- package/src/brand-page-maker/__fixtures__/complex-rte.fixture.ts +0 -23
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.test.ts +0 -52
- package/src/brand-page-maker/composables/rich-text-editor/extensions/FontFamily.ts +0 -42
- package/src/brand-page-maker/composables/rich-text-editor/getRteExtensions.ts +0 -137
- package/src/brand-page-maker/utils/__snapshots__/rte-render-parity.test.ts.snap +0 -202
- package/src/brand-page-maker/utils/rte-features.test.ts +0 -351
- package/src/brand-page-maker/utils/rte-render-parity.test.ts +0 -157
- package/src/brand-page-maker/utils/rte-render.util.ts +0 -165
- package/src/brand-page-maker/utils/rte-sanitize-json.test.ts +0 -158
- package/src/brand-page-maker/utils/rte-sanitize.util.ts +0 -195
- package/src/brand-page-maker/validators/field.validator.test.ts +0 -55
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import type { BrandPageModel, Content } from '../../brand-page/models';
|
|
3
|
+
import type { UpdateGlobalStylesArguments } from '../parsers/ai-toolcall-parser';
|
|
4
|
+
import { BUILDER_TYPES } from '../models';
|
|
5
|
+
import { GlobalStylesBuilder } from './global-styles-builder';
|
|
6
|
+
import {
|
|
7
|
+
collectChangedFontFamilies,
|
|
8
|
+
propagateFontFamiliesToContents,
|
|
9
|
+
} from './global-font-propagation';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* BP-5780 ISSUE-01: an AI global font change only reached preset-bound content.
|
|
13
|
+
* Template-authored sections carry detached `*Style` objects and inline RTE
|
|
14
|
+
* `font-family` marks that override the preset at render, so "use a serif font"
|
|
15
|
+
* produced a confident reply and a pixel-identical page. Propagation must align
|
|
16
|
+
* detached styles and rewrite inline marks for every changed category.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const RTE_TITLE =
|
|
20
|
+
'<p><span style="font-family: Playfair Display">Bloom</span></p>';
|
|
21
|
+
|
|
22
|
+
// Injectable stand-in for the Tiptap rewrite — tags the string so tests can
|
|
23
|
+
// assert exactly which fields were rewritten and with which family.
|
|
24
|
+
const fakeApplyFont = (text: string, fontFamily: string) =>
|
|
25
|
+
`${text}::rewritten(${fontFamily})`;
|
|
26
|
+
|
|
27
|
+
const makeModel = (contents: Partial<Content>[]): BrandPageModel =>
|
|
28
|
+
({
|
|
29
|
+
styles: { textStyles: { textStyleOptions: {} } },
|
|
30
|
+
pages: [{ id: 'p1', contents }],
|
|
31
|
+
}) as unknown as BrandPageModel;
|
|
32
|
+
|
|
33
|
+
describe('collectChangedFontFamilies', () => {
|
|
34
|
+
it('extracts per-category families from textStyleOptions', () => {
|
|
35
|
+
const changed = collectChangedFontFamilies({
|
|
36
|
+
textStyleOptions: {
|
|
37
|
+
titles: { style: { fontFamily: 'EB Garamond' } },
|
|
38
|
+
headings: { style: { fontFamily: 'EB Garamond' } },
|
|
39
|
+
buttons: { style: { fontFamily: 'Inter' } },
|
|
40
|
+
},
|
|
41
|
+
} as UpdateGlobalStylesArguments['textStyles']);
|
|
42
|
+
|
|
43
|
+
expect(changed).toEqual({
|
|
44
|
+
titles: 'EB Garamond',
|
|
45
|
+
headings: 'EB Garamond',
|
|
46
|
+
buttons: 'Inter',
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('falls back textFontFamily → paragraphs when no explicit paragraphs entry', () => {
|
|
51
|
+
const changed = collectChangedFontFamilies({
|
|
52
|
+
textFontFamily: 'Inter',
|
|
53
|
+
} as UpdateGlobalStylesArguments['textStyles']);
|
|
54
|
+
|
|
55
|
+
expect(changed).toEqual({ paragraphs: 'Inter' });
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('returns empty for calls that change no fonts', () => {
|
|
59
|
+
expect(collectChangedFontFamilies(undefined)).toEqual({});
|
|
60
|
+
expect(
|
|
61
|
+
collectChangedFontFamilies({
|
|
62
|
+
style: { color: '#111111' },
|
|
63
|
+
} as UpdateGlobalStylesArguments['textStyles']),
|
|
64
|
+
).toEqual({});
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
describe('propagateFontFamiliesToContents', () => {
|
|
69
|
+
it('aligns detached styles and rewrites RTE marks for the changed category', () => {
|
|
70
|
+
const content = {
|
|
71
|
+
id: 'c1',
|
|
72
|
+
type: 'about-section',
|
|
73
|
+
title: RTE_TITLE,
|
|
74
|
+
titleStyle: { fontFamily: 'Playfair Display' },
|
|
75
|
+
} as unknown as Content;
|
|
76
|
+
const model = makeModel([content]);
|
|
77
|
+
|
|
78
|
+
propagateFontFamiliesToContents(
|
|
79
|
+
model,
|
|
80
|
+
{ headings: 'EB Garamond' },
|
|
81
|
+
fakeApplyFont,
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
const c = model.pages[0].contents[0] as unknown as Record<string, unknown>;
|
|
85
|
+
|
|
86
|
+
expect((c.titleStyle as Record<string, unknown>).fontFamily).toBe(
|
|
87
|
+
'EB Garamond',
|
|
88
|
+
);
|
|
89
|
+
expect(c.title).toBe(`${RTE_TITLE}::rewritten(EB Garamond)`);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
it('banner-section titles follow the titles category, not headings', () => {
|
|
93
|
+
const content = {
|
|
94
|
+
id: 'c1',
|
|
95
|
+
type: 'banner-section',
|
|
96
|
+
title: RTE_TITLE,
|
|
97
|
+
titleStyle: { fontFamily: 'Playfair Display' },
|
|
98
|
+
} as unknown as Content;
|
|
99
|
+
const model = makeModel([content]);
|
|
100
|
+
|
|
101
|
+
propagateFontFamiliesToContents(
|
|
102
|
+
model,
|
|
103
|
+
{ titles: 'Lexend Deca', headings: 'EB Garamond' },
|
|
104
|
+
fakeApplyFont,
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const c = model.pages[0].contents[0] as unknown as Record<string, unknown>;
|
|
108
|
+
|
|
109
|
+
expect((c.titleStyle as Record<string, unknown>).fontFamily).toBe(
|
|
110
|
+
'Lexend Deca',
|
|
111
|
+
);
|
|
112
|
+
expect(c.title).toBe(`${RTE_TITLE}::rewritten(Lexend Deca)`);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
it('preset-bound styles stay preset-bound; only their RTE marks are rewritten', () => {
|
|
116
|
+
const content = {
|
|
117
|
+
id: 'c1',
|
|
118
|
+
type: 'about-section',
|
|
119
|
+
title: RTE_TITLE,
|
|
120
|
+
titleStyle: { textStyleType: 'headings' },
|
|
121
|
+
} as unknown as Content;
|
|
122
|
+
const model = makeModel([content]);
|
|
123
|
+
|
|
124
|
+
propagateFontFamiliesToContents(
|
|
125
|
+
model,
|
|
126
|
+
{ headings: 'EB Garamond' },
|
|
127
|
+
fakeApplyFont,
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
const c = model.pages[0].contents[0] as unknown as Record<string, unknown>;
|
|
131
|
+
const style = c.titleStyle as unknown as Record<string, unknown>;
|
|
132
|
+
|
|
133
|
+
expect(style.textStyleType).toBe('headings');
|
|
134
|
+
expect(style.fontFamily).toBeUndefined();
|
|
135
|
+
expect(c.title).toBe(`${RTE_TITLE}::rewritten(EB Garamond)`);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('walks items arrays (per-item text fields and styles)', () => {
|
|
139
|
+
const itemText = '<p>Live music</p>';
|
|
140
|
+
const content = {
|
|
141
|
+
id: 'c1',
|
|
142
|
+
type: 'shapes-section',
|
|
143
|
+
items: [
|
|
144
|
+
{
|
|
145
|
+
heading: itemText,
|
|
146
|
+
headingStyle: { fontFamily: 'Playfair Display' },
|
|
147
|
+
text: itemText,
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
} as unknown as Content;
|
|
151
|
+
const model = makeModel([content]);
|
|
152
|
+
|
|
153
|
+
propagateFontFamiliesToContents(
|
|
154
|
+
model,
|
|
155
|
+
{ headings: 'EB Garamond', paragraphs: 'Inter' },
|
|
156
|
+
fakeApplyFont,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
const item = (
|
|
160
|
+
model.pages[0].contents[0] as unknown as Record<string, unknown>
|
|
161
|
+
).items as Record<string, unknown>[];
|
|
162
|
+
|
|
163
|
+
expect((item[0].headingStyle as Record<string, unknown>).fontFamily).toBe(
|
|
164
|
+
'EB Garamond',
|
|
165
|
+
);
|
|
166
|
+
expect(item[0].heading).toBe(`${itemText}::rewritten(EB Garamond)`);
|
|
167
|
+
expect(item[0].text).toBe(`${itemText}::rewritten(Inter)`);
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
it('leaves fields alone when their category did not change', () => {
|
|
171
|
+
const content = {
|
|
172
|
+
id: 'c1',
|
|
173
|
+
type: 'about-section',
|
|
174
|
+
title: RTE_TITLE,
|
|
175
|
+
titleStyle: { fontFamily: 'Playfair Display' },
|
|
176
|
+
description: RTE_TITLE,
|
|
177
|
+
descriptionStyle: { fontFamily: 'Lato' },
|
|
178
|
+
} as unknown as Content;
|
|
179
|
+
const model = makeModel([content]);
|
|
180
|
+
|
|
181
|
+
propagateFontFamiliesToContents(
|
|
182
|
+
model,
|
|
183
|
+
{ paragraphs: 'Inter' },
|
|
184
|
+
fakeApplyFont,
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
const c = model.pages[0].contents[0] as unknown as Record<string, unknown>;
|
|
188
|
+
|
|
189
|
+
expect((c.titleStyle as Record<string, unknown>).fontFamily).toBe(
|
|
190
|
+
'Playfair Display',
|
|
191
|
+
);
|
|
192
|
+
expect(c.title).toBe(RTE_TITLE);
|
|
193
|
+
expect((c.descriptionStyle as Record<string, unknown>).fontFamily).toBe(
|
|
194
|
+
'Inter',
|
|
195
|
+
);
|
|
196
|
+
expect(c.description).toBe(`${RTE_TITLE}::rewritten(Inter)`);
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('non-RTE plain text fields are not rewritten (style still aligned)', () => {
|
|
200
|
+
const content = {
|
|
201
|
+
id: 'c1',
|
|
202
|
+
type: 'about-section',
|
|
203
|
+
title: 'Plain title',
|
|
204
|
+
titleStyle: { fontFamily: 'Playfair Display' },
|
|
205
|
+
} as unknown as Content;
|
|
206
|
+
const model = makeModel([content]);
|
|
207
|
+
|
|
208
|
+
propagateFontFamiliesToContents(
|
|
209
|
+
model,
|
|
210
|
+
{ headings: 'EB Garamond' },
|
|
211
|
+
fakeApplyFont,
|
|
212
|
+
);
|
|
213
|
+
|
|
214
|
+
const c = model.pages[0].contents[0] as unknown as Record<string, unknown>;
|
|
215
|
+
|
|
216
|
+
expect(c.title).toBe('Plain title');
|
|
217
|
+
expect((c.titleStyle as Record<string, unknown>).fontFamily).toBe(
|
|
218
|
+
'EB Garamond',
|
|
219
|
+
);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
describe('GlobalStylesBuilder font propagation wiring', () => {
|
|
224
|
+
it('buildAsync propagates changed category families into existing detached styles', async () => {
|
|
225
|
+
const content = {
|
|
226
|
+
id: 'c1',
|
|
227
|
+
type: 'about-section',
|
|
228
|
+
title: 'Plain title', // plain text — the builder path must not need the RTE editor here
|
|
229
|
+
titleStyle: { fontFamily: 'Playfair Display' },
|
|
230
|
+
} as unknown as Content;
|
|
231
|
+
const model = {
|
|
232
|
+
styles: {
|
|
233
|
+
textStyles: {
|
|
234
|
+
textStyleOptions: {
|
|
235
|
+
headings: { style: { fontFamily: 'Lato' }, isModified: false },
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
buttonStyles: { style: {} },
|
|
239
|
+
backgroundStyles: { style: {} },
|
|
240
|
+
},
|
|
241
|
+
pages: [{ id: 'p1', contents: [content] }],
|
|
242
|
+
} as unknown as BrandPageModel;
|
|
243
|
+
|
|
244
|
+
const builder = new GlobalStylesBuilder({
|
|
245
|
+
id: 'g1',
|
|
246
|
+
type: BUILDER_TYPES.UPDATE_GLOBAL_STYLES,
|
|
247
|
+
payload: {
|
|
248
|
+
textStyles: {
|
|
249
|
+
textStyleOptions: {
|
|
250
|
+
headings: { style: { fontFamily: 'EB Garamond' } },
|
|
251
|
+
},
|
|
252
|
+
},
|
|
253
|
+
} as UpdateGlobalStylesArguments,
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
const result = await builder.buildAsync(model);
|
|
257
|
+
|
|
258
|
+
expect(result.errors).toBeUndefined();
|
|
259
|
+
// Preset updated (pre-existing behaviour)…
|
|
260
|
+
expect(
|
|
261
|
+
model.styles.textStyles.textStyleOptions.headings.style.fontFamily,
|
|
262
|
+
).toBe('EB Garamond');
|
|
263
|
+
// …AND the detached section style now follows (the fix).
|
|
264
|
+
expect(
|
|
265
|
+
(model.pages[0].contents[0] as unknown as Record<string, unknown>)
|
|
266
|
+
.titleStyle,
|
|
267
|
+
).toMatchObject({ fontFamily: 'EB Garamond' });
|
|
268
|
+
});
|
|
269
|
+
});
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { BrandPageModel, Content } from '../../brand-page/models';
|
|
2
|
+
import type { TextStyleDeclaration } from '../../brand-page/models';
|
|
3
|
+
import { hasRTEContent } from '../../brand-page-maker/utils';
|
|
4
|
+
import { useExternalRichTextEditor } from '../../brand-page-maker/composables/rich-text-editor/useRichTextEditor';
|
|
5
|
+
import { applyStyleToRTEText } from '../helpers/rte.helpers';
|
|
6
|
+
import type { UpdateGlobalStylesArguments } from '../parsers/ai-toolcall-parser';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Propagation of AI global font-family changes into existing section content.
|
|
10
|
+
*
|
|
11
|
+
* A `tool_update_global_styles` call merges new per-category font families into
|
|
12
|
+
* `styles.textStyles.textStyleOptions` — but only content whose style is still
|
|
13
|
+
* bound to a preset (`textStyleType`) follows that change. Template-authored
|
|
14
|
+
* content carries detached `*Style` objects AND inline `font-family` marks in
|
|
15
|
+
* its RTE HTML, both of which override the preset at render time, so a global
|
|
16
|
+
* font change was invisible on most templates (BP-5780 ISSUE-01).
|
|
17
|
+
*
|
|
18
|
+
* This module walks every page's contents and, for each text field whose
|
|
19
|
+
* resolved category received a new family, aligns the detached style object and
|
|
20
|
+
* rewrites the RTE HTML's inline font-family marks. Preset-bound styles are NOT
|
|
21
|
+
* detached — they already follow the preset; only their RTE inline marks are
|
|
22
|
+
* rewritten (the marks would otherwise still win over the preset).
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export type GlobalFontCategory =
|
|
26
|
+
| 'titles'
|
|
27
|
+
| 'headings'
|
|
28
|
+
| 'paragraphs'
|
|
29
|
+
| 'buttons';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Default category per text field when its style is detached (no `textStyleType`).
|
|
33
|
+
* Mirrors the AI service's slot→category stamping (titles←h1, headings←h2-h4,
|
|
34
|
+
* paragraphs←body, buttons←button). `title` upgrades to `titles` on banner
|
|
35
|
+
* sections (the hero headline) via `resolveFieldCategory`.
|
|
36
|
+
*/
|
|
37
|
+
const FIELD_DEFAULT_CATEGORY: Record<string, GlobalFontCategory> = {
|
|
38
|
+
title: 'headings',
|
|
39
|
+
heading: 'headings',
|
|
40
|
+
name: 'headings',
|
|
41
|
+
description: 'paragraphs',
|
|
42
|
+
paragraph: 'paragraphs',
|
|
43
|
+
text: 'paragraphs',
|
|
44
|
+
testimonial: 'paragraphs',
|
|
45
|
+
position: 'paragraphs',
|
|
46
|
+
question: 'headings',
|
|
47
|
+
answer: 'paragraphs',
|
|
48
|
+
buttonText: 'buttons',
|
|
49
|
+
successMessage: 'paragraphs',
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const CATEGORIES: readonly GlobalFontCategory[] = [
|
|
53
|
+
'titles',
|
|
54
|
+
'headings',
|
|
55
|
+
'paragraphs',
|
|
56
|
+
'buttons',
|
|
57
|
+
];
|
|
58
|
+
|
|
59
|
+
const isPlainObject = (v: unknown): v is Record<string, unknown> =>
|
|
60
|
+
!!v && typeof v === 'object' && !Array.isArray(v);
|
|
61
|
+
|
|
62
|
+
/** Extract the per-category families this AI call actually changes. */
|
|
63
|
+
export const collectChangedFontFamilies = (
|
|
64
|
+
textStyles: UpdateGlobalStylesArguments['textStyles'],
|
|
65
|
+
): Partial<Record<GlobalFontCategory, string>> => {
|
|
66
|
+
const changed: Partial<Record<GlobalFontCategory, string>> = {};
|
|
67
|
+
|
|
68
|
+
if (!textStyles) return changed;
|
|
69
|
+
|
|
70
|
+
for (const category of CATEGORIES) {
|
|
71
|
+
const family = textStyles.textStyleOptions?.[category]?.style?.fontFamily;
|
|
72
|
+
|
|
73
|
+
if (typeof family === 'string' && family.trim()) {
|
|
74
|
+
changed[category] = family;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Base text family covers paragraphs when no explicit paragraphs entry came in.
|
|
79
|
+
if (
|
|
80
|
+
!changed.paragraphs &&
|
|
81
|
+
typeof textStyles.textFontFamily === 'string' &&
|
|
82
|
+
textStyles.textFontFamily.trim()
|
|
83
|
+
) {
|
|
84
|
+
changed.paragraphs = textStyles.textFontFamily;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return changed;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const resolveFieldCategory = (
|
|
91
|
+
fieldName: string,
|
|
92
|
+
style: unknown,
|
|
93
|
+
content: Content,
|
|
94
|
+
): GlobalFontCategory | undefined => {
|
|
95
|
+
const preset = isPlainObject(style)
|
|
96
|
+
? (style.textStyleType as GlobalFontCategory | undefined)
|
|
97
|
+
: undefined;
|
|
98
|
+
|
|
99
|
+
if (preset && CATEGORIES.includes(preset)) return preset;
|
|
100
|
+
|
|
101
|
+
if (fieldName === 'title' && content.type === 'banner-section') {
|
|
102
|
+
return 'titles';
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
return FIELD_DEFAULT_CATEGORY[fieldName];
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
/** `testimonialsStyle` → `testimonial`, `titleStyle` → `title`. */
|
|
109
|
+
const styleKeyToFieldName = (styleKey: string): string => {
|
|
110
|
+
const base = styleKey.slice(0, -'Style'.length);
|
|
111
|
+
|
|
112
|
+
return base.endsWith('s') && !(base in FIELD_DEFAULT_CATEGORY)
|
|
113
|
+
? base.slice(0, -1)
|
|
114
|
+
: base;
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
export type ApplyFontToRTE = (text: string, fontFamily: string) => string;
|
|
118
|
+
|
|
119
|
+
const walkRecord = (
|
|
120
|
+
record: Record<string, unknown>,
|
|
121
|
+
content: Content,
|
|
122
|
+
changed: Partial<Record<GlobalFontCategory, string>>,
|
|
123
|
+
applyFont: ApplyFontToRTE,
|
|
124
|
+
): void => {
|
|
125
|
+
for (const [key, value] of Object.entries(record)) {
|
|
126
|
+
if (key.endsWith('Style') && isPlainObject(value)) {
|
|
127
|
+
// Detached style objects carry their own fontFamily override — align it.
|
|
128
|
+
// Preset-bound styles keep following the preset (never detach here).
|
|
129
|
+
const category = resolveFieldCategory(
|
|
130
|
+
styleKeyToFieldName(key),
|
|
131
|
+
value,
|
|
132
|
+
content,
|
|
133
|
+
);
|
|
134
|
+
const family = category ? changed[category] : undefined;
|
|
135
|
+
|
|
136
|
+
if (family && !value.textStyleType) {
|
|
137
|
+
(value as TextStyleDeclaration).fontFamily =
|
|
138
|
+
family as TextStyleDeclaration['fontFamily'];
|
|
139
|
+
}
|
|
140
|
+
} else if (
|
|
141
|
+
key in FIELD_DEFAULT_CATEGORY &&
|
|
142
|
+
typeof value === 'string' &&
|
|
143
|
+
hasRTEContent(value)
|
|
144
|
+
) {
|
|
145
|
+
// Inline RTE marks override every style layer at render — rewrite them.
|
|
146
|
+
const category = resolveFieldCategory(
|
|
147
|
+
key,
|
|
148
|
+
record[`${key}Style`],
|
|
149
|
+
content,
|
|
150
|
+
);
|
|
151
|
+
const family = category ? changed[category] : undefined;
|
|
152
|
+
|
|
153
|
+
if (family) {
|
|
154
|
+
record[key] = applyFont(value, family);
|
|
155
|
+
}
|
|
156
|
+
} else if (Array.isArray(value)) {
|
|
157
|
+
for (const item of value) {
|
|
158
|
+
if (isPlainObject(item)) {
|
|
159
|
+
walkRecord(item, content, changed, applyFont);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Walk every page's contents and propagate the changed families.
|
|
168
|
+
* `applyFont` is injectable for tests; the default rewrites inline marks via
|
|
169
|
+
* the external Tiptap editor.
|
|
170
|
+
*/
|
|
171
|
+
export const propagateFontFamiliesToContents = (
|
|
172
|
+
model: BrandPageModel,
|
|
173
|
+
changed: Partial<Record<GlobalFontCategory, string>>,
|
|
174
|
+
applyFont?: ApplyFontToRTE,
|
|
175
|
+
): void => {
|
|
176
|
+
if (!Object.keys(changed).length) return;
|
|
177
|
+
|
|
178
|
+
let editor:
|
|
179
|
+
| ReturnType<typeof useExternalRichTextEditor>['externalEditor']
|
|
180
|
+
| undefined;
|
|
181
|
+
const apply: ApplyFontToRTE =
|
|
182
|
+
applyFont ??
|
|
183
|
+
((text, fontFamily) => {
|
|
184
|
+
editor = editor ?? useExternalRichTextEditor().externalEditor;
|
|
185
|
+
|
|
186
|
+
return applyStyleToRTEText(editor, text, {
|
|
187
|
+
fontFamily,
|
|
188
|
+
} as TextStyleDeclaration);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
try {
|
|
192
|
+
for (const page of model.pages) {
|
|
193
|
+
for (const content of page.contents) {
|
|
194
|
+
walkRecord(
|
|
195
|
+
content as unknown as Record<string, unknown>,
|
|
196
|
+
content,
|
|
197
|
+
changed,
|
|
198
|
+
apply,
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
} finally {
|
|
203
|
+
editor?.destroy();
|
|
204
|
+
}
|
|
205
|
+
};
|
|
@@ -14,6 +14,10 @@ import {
|
|
|
14
14
|
GLOBAL_STYLE_CHECKS,
|
|
15
15
|
TEXT_STYLE_OPTION_KEYS,
|
|
16
16
|
} from './section-rules/global-styles.rules';
|
|
17
|
+
import {
|
|
18
|
+
collectChangedFontFamilies,
|
|
19
|
+
propagateFontFamiliesToContents,
|
|
20
|
+
} from './global-font-propagation';
|
|
17
21
|
|
|
18
22
|
export class GlobalStylesBuilder extends BaseMetadataBuilder<UpdateGlobalStylesArguments> {
|
|
19
23
|
constructor(
|
|
@@ -54,6 +58,23 @@ export class GlobalStylesBuilder extends BaseMetadataBuilder<UpdateGlobalStylesA
|
|
|
54
58
|
|
|
55
59
|
if (args.textStyles) {
|
|
56
60
|
this.applyTextStyles(model, args.textStyles);
|
|
61
|
+
|
|
62
|
+
// A category font change only reaches preset-bound content by itself;
|
|
63
|
+
// detached section styles and inline RTE font marks would still render
|
|
64
|
+
// the old family. Propagate so the change is actually visible (BP-5780).
|
|
65
|
+
const changedFamilies = collectChangedFontFamilies(args.textStyles);
|
|
66
|
+
|
|
67
|
+
if (Object.keys(changedFamilies).length) {
|
|
68
|
+
try {
|
|
69
|
+
propagateFontFamiliesToContents(model, changedFamilies);
|
|
70
|
+
} catch (error) {
|
|
71
|
+
this.log({
|
|
72
|
+
message:
|
|
73
|
+
'Global font propagation to existing contents failed — presets still updated',
|
|
74
|
+
error,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
57
78
|
}
|
|
58
79
|
|
|
59
80
|
if (args.buttonStyles) {
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
BrandPageModel,
|
|
4
4
|
TextStyleDeclaration,
|
|
5
5
|
} from '../../../brand-page/models';
|
|
6
|
+
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
6
7
|
import type { BuilderResult } from '../../models';
|
|
7
8
|
import {
|
|
8
9
|
isTiptapDocument,
|
|
@@ -53,7 +54,7 @@ export class AboutSectionBuilder extends BaseSectionBuilder<AboutSectionContent>
|
|
|
53
54
|
|
|
54
55
|
if (aboutArgs.title !== undefined) {
|
|
55
56
|
if (isTiptapDocument(aboutArgs.title)) {
|
|
56
|
-
resolved.content.title = aboutArgs.title;
|
|
57
|
+
resolved.content.title = tiptapJsonToHtml(aboutArgs.title);
|
|
57
58
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(
|
|
58
59
|
resolved.content.titleStyle,
|
|
59
60
|
textStyleOptions,
|
|
@@ -65,7 +66,7 @@ export class AboutSectionBuilder extends BaseSectionBuilder<AboutSectionContent>
|
|
|
65
66
|
|
|
66
67
|
if (aboutArgs.paragraph !== undefined) {
|
|
67
68
|
if (isTiptapDocument(aboutArgs.paragraph)) {
|
|
68
|
-
resolved.content.paragraph = aboutArgs.paragraph;
|
|
69
|
+
resolved.content.paragraph = tiptapJsonToHtml(aboutArgs.paragraph);
|
|
69
70
|
resolved.content.paragraphStyle = resolveGlobalPresetIntoStyle(
|
|
70
71
|
resolved.content.paragraphStyle,
|
|
71
72
|
textStyleOptions,
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
BrandPageModel,
|
|
4
4
|
TextStyleDeclaration,
|
|
5
5
|
} from '../../../brand-page/models';
|
|
6
|
+
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
6
7
|
import type { BuilderResult } from '../../models';
|
|
7
8
|
import {
|
|
8
9
|
isTiptapDocument,
|
|
@@ -90,7 +91,7 @@ export class BannerSectionBuilder extends BaseSectionBuilder<BannerSectionConten
|
|
|
90
91
|
|
|
91
92
|
if (bannerArgs.title !== undefined) {
|
|
92
93
|
if (isTiptapDocument(bannerArgs.title)) {
|
|
93
|
-
resolved.content.title = bannerArgs.title;
|
|
94
|
+
resolved.content.title = tiptapJsonToHtml(bannerArgs.title);
|
|
94
95
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(
|
|
95
96
|
resolved.content.titleStyle,
|
|
96
97
|
textStyleOptions,
|
|
@@ -102,7 +103,7 @@ export class BannerSectionBuilder extends BaseSectionBuilder<BannerSectionConten
|
|
|
102
103
|
|
|
103
104
|
if (bannerArgs.description !== undefined) {
|
|
104
105
|
if (isTiptapDocument(bannerArgs.description)) {
|
|
105
|
-
resolved.content.description = bannerArgs.description;
|
|
106
|
+
resolved.content.description = tiptapJsonToHtml(bannerArgs.description);
|
|
106
107
|
resolved.content.descriptionStyle = resolveGlobalPresetIntoStyle(
|
|
107
108
|
resolved.content.descriptionStyle,
|
|
108
109
|
textStyleOptions,
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
BrandPageModel,
|
|
4
4
|
TextStyleDeclaration,
|
|
5
5
|
} from '../../../brand-page/models';
|
|
6
|
+
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
6
7
|
import type { BuilderResult } from '../../models';
|
|
7
8
|
import {
|
|
8
9
|
isTiptapDocument,
|
|
@@ -50,7 +51,7 @@ export class BookingSectionBuilder extends BaseSectionBuilder<BookingSectionCont
|
|
|
50
51
|
|
|
51
52
|
if (bookingArgs.title !== undefined) {
|
|
52
53
|
if (isTiptapDocument(bookingArgs.title)) {
|
|
53
|
-
resolved.content.title = bookingArgs.title;
|
|
54
|
+
resolved.content.title = tiptapJsonToHtml(bookingArgs.title);
|
|
54
55
|
resolved.content.titleStyle = resolveGlobalPresetIntoStyle(
|
|
55
56
|
resolved.content.titleStyle,
|
|
56
57
|
textStyleOptions,
|
|
@@ -62,7 +63,9 @@ export class BookingSectionBuilder extends BaseSectionBuilder<BookingSectionCont
|
|
|
62
63
|
|
|
63
64
|
if (bookingArgs.description !== undefined) {
|
|
64
65
|
if (isTiptapDocument(bookingArgs.description)) {
|
|
65
|
-
resolved.content.description =
|
|
66
|
+
resolved.content.description = tiptapJsonToHtml(
|
|
67
|
+
bookingArgs.description,
|
|
68
|
+
);
|
|
66
69
|
resolved.content.descriptionStyle = resolveGlobalPresetIntoStyle(
|
|
67
70
|
resolved.content.descriptionStyle,
|
|
68
71
|
textStyleOptions,
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
BrandPageModel,
|
|
4
4
|
TextStyleDeclaration,
|
|
5
5
|
} from '../../../brand-page/models';
|
|
6
|
+
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
6
7
|
import {
|
|
7
8
|
isTiptapDocument,
|
|
8
9
|
type ContactFormSectionArguments,
|
|
@@ -49,7 +50,7 @@ export class ContactFormBuilder extends BaseSectionBuilder<ContactFormContent> {
|
|
|
49
50
|
|
|
50
51
|
if (args.title !== undefined) {
|
|
51
52
|
if (isTiptapDocument(args.title)) {
|
|
52
|
-
content.title = args.title;
|
|
53
|
+
content.title = tiptapJsonToHtml(args.title);
|
|
53
54
|
content.titleStyle = resolveGlobalPresetIntoStyle(
|
|
54
55
|
content.titleStyle,
|
|
55
56
|
textStyleOptions,
|
|
@@ -61,7 +62,7 @@ export class ContactFormBuilder extends BaseSectionBuilder<ContactFormContent> {
|
|
|
61
62
|
|
|
62
63
|
if (args.description !== undefined) {
|
|
63
64
|
if (isTiptapDocument(args.description)) {
|
|
64
|
-
content.description = args.description;
|
|
65
|
+
content.description = tiptapJsonToHtml(args.description);
|
|
65
66
|
content.descriptionStyle = resolveGlobalPresetIntoStyle(
|
|
66
67
|
content.descriptionStyle,
|
|
67
68
|
textStyleOptions,
|
|
@@ -73,7 +74,7 @@ export class ContactFormBuilder extends BaseSectionBuilder<ContactFormContent> {
|
|
|
73
74
|
|
|
74
75
|
if (args.success_message !== undefined) {
|
|
75
76
|
if (isTiptapDocument(args.success_message)) {
|
|
76
|
-
content.successMessage = args.success_message;
|
|
77
|
+
content.successMessage = tiptapJsonToHtml(args.success_message);
|
|
77
78
|
content.successMessageStyle = resolveGlobalPresetIntoStyle(
|
|
78
79
|
content.successMessageStyle,
|
|
79
80
|
textStyleOptions,
|
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
BrandPageModel,
|
|
4
4
|
TextStyleDeclaration,
|
|
5
5
|
} from '../../../brand-page/models';
|
|
6
|
+
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
6
7
|
import type { BuilderResult } from '../../models';
|
|
7
8
|
import {
|
|
8
9
|
isTiptapDocument,
|
|
@@ -141,7 +142,7 @@ export class ImagesSectionBuilder extends BaseSectionBuilder<ImagesSectionConten
|
|
|
141
142
|
|
|
142
143
|
if (args.title !== undefined) {
|
|
143
144
|
if (isTiptapDocument(args.title)) {
|
|
144
|
-
content.title = args.title;
|
|
145
|
+
content.title = tiptapJsonToHtml(args.title);
|
|
145
146
|
content.titleStyle = resolveGlobalPresetIntoStyle(
|
|
146
147
|
content.titleStyle,
|
|
147
148
|
textStyleOptions,
|
|
@@ -153,7 +154,7 @@ export class ImagesSectionBuilder extends BaseSectionBuilder<ImagesSectionConten
|
|
|
153
154
|
|
|
154
155
|
if (args.description !== undefined) {
|
|
155
156
|
if (isTiptapDocument(args.description)) {
|
|
156
|
-
content.description = args.description;
|
|
157
|
+
content.description = tiptapJsonToHtml(args.description);
|
|
157
158
|
content.descriptionStyle = resolveGlobalPresetIntoStyle(
|
|
158
159
|
content.descriptionStyle,
|
|
159
160
|
textStyleOptions,
|
|
@@ -5,6 +5,7 @@ export {
|
|
|
5
5
|
|
|
6
6
|
export { BannerSectionBuilder } from './banner-section-builder';
|
|
7
7
|
export { BookingSectionBuilder } from './booking-section-builder';
|
|
8
|
+
export { SupportMeBuilder } from './support-me-builder';
|
|
8
9
|
export { AboutSectionBuilder } from './about-section-builder';
|
|
9
10
|
export { ContactFormBuilder } from './contact-form-builder';
|
|
10
11
|
export { DividerSectionBuilder } from './divider-section-builder';
|
|
@@ -4,6 +4,7 @@ import type {
|
|
|
4
4
|
MailingListContent,
|
|
5
5
|
TextStyleDeclaration,
|
|
6
6
|
} from '../../../brand-page/models';
|
|
7
|
+
import { tiptapJsonToHtml } from '../../helpers/rte.helpers';
|
|
7
8
|
import {
|
|
8
9
|
isTiptapDocument,
|
|
9
10
|
type MailingListSectionArguments,
|
|
@@ -49,7 +50,7 @@ export class MailingListBuilder extends BaseSectionBuilder<MailingListContent> {
|
|
|
49
50
|
|
|
50
51
|
if (mailingListArgs.title !== undefined) {
|
|
51
52
|
if (isTiptapDocument(mailingListArgs.title)) {
|
|
52
|
-
content.title = mailingListArgs.title;
|
|
53
|
+
content.title = tiptapJsonToHtml(mailingListArgs.title);
|
|
53
54
|
content.titleStyle = resolveGlobalPresetIntoStyle(
|
|
54
55
|
content.titleStyle,
|
|
55
56
|
textStyleOptions,
|