@designcrowd/library.brand-page 5.16.3 → 5.16.4-abtest-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-BVouwZJN.js → CreatedOnBrandCrowd-de-de-DQc3IjpR.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-Dtx-1uWO.js → CreatedOnBrandCrowd-en-us-CIgIJjzf.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-CmlnW8oC.js → CreatedOnBrandCrowd-es-es-C4JLISvP.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-C95ioWzr.js → CreatedOnBrandCrowd-fr-ca-DPpWX0aJ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-C95ioWzr.js → CreatedOnBrandCrowd-fr-fr-DPpWX0aJ.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-C_5SiaiE.js → CreatedOnBrandCrowd-pt-br-DmKD5o2o.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-C_5SiaiE.js → CreatedOnBrandCrowd-pt-pt-DmKD5o2o.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-BP4saQXn.js → CreatedOnDcom-de-de-DhALOqwz.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-B8Taru6f.js → CreatedOnDcom-en-us-LmejZqTn.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-Bo3JhWwd.js → CreatedOnDcom-es-es-D3ZH5JD5.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-CDk3ZAHU.js → CreatedOnDcom-fr-ca-BUOMh8kU.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-CD04W_hw.js → CreatedOnDcom-fr-fr-CNc-56QW.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-B2DGv1qj.js → CreatedOnDcom-pt-br-BGvy2ON7.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-TYqvgQ08.js → CreatedOnDcom-pt-pt-FaVxQHpN.js} +1 -1
- package/lib/src/brand-page/models/brand-page-context.model.d.ts +1 -1
- package/lib/src/brand-page/models/brand-page-context.model.js +5 -1
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +13 -0
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.js +30 -1
- package/lib/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.js +0 -12
- package/lib/src/brand-page-maker/stores/index.d.ts +1 -0
- package/lib/src/brand-page-maker/stores/index.js +1 -0
- package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.d.ts +14 -0
- package/lib/src/brand-page-maker/stores/snapshot/snapshot-store.js +21 -0
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.d.ts +2 -0
- package/lib/src/brand-page-maker/utils/rich-text-editor.util.js +117 -0
- package/lib/src/bundled-translations-Dw3XtNmX.js +163 -0
- package/lib/src/bundled-translations.de-DE-B82Ik9M7.js +163 -0
- package/lib/src/bundled-translations.es-ES-cf3pdNuN.js +163 -0
- package/lib/src/bundled-translations.fr-CA-DP44EcAZ.js +163 -0
- package/lib/src/bundled-translations.fr-FR-V0Zt25kg.js +163 -0
- package/lib/src/bundled-translations.pt-BR-Brv6rCss.js +163 -0
- package/lib/src/bundled-translations.pt-PT-BTgscCTG.js +163 -0
- package/lib/src/bundles/bundled-translations.de-DE.json +15 -1
- package/lib/src/bundles/bundled-translations.es-ES.json +15 -1
- package/lib/src/bundles/bundled-translations.fr-CA.json +15 -1
- package/lib/src/bundles/bundled-translations.fr-FR.json +15 -1
- package/lib/src/bundles/bundled-translations.json +15 -1
- package/lib/src/bundles/bundled-translations.pt-BR.json +15 -1
- package/lib/src/bundles/bundled-translations.pt-PT.json +15 -1
- package/lib/src/clients/brand-page-client.d.ts +0 -4
- package/lib/src/clients/design-template-client.d.ts +2 -0
- package/lib/src/clients/design-template-client.js +33 -0
- package/lib/src/composables/useSnapshot.d.ts +5 -0
- package/lib/src/composables/useSnapshot.js +74 -0
- package/lib/src/composables/useTranslate.d.ts +2 -1
- package/lib/src/composables/useTranslate.js +2 -1
- package/lib/src/css/library.brand-page-brandCrowd.min.css +149 -8
- package/lib/src/css/library.brand-page-brandPage.min.css +136 -8
- package/lib/src/css/library.brand-page-designCom.min.css +149 -8
- package/lib/src/css/library.brand-page-preview.min.css +133 -8
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-3sE17Ltm.js → lib-CqA2Cr9V.js} +20353 -19606
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +1 -0
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.js +3 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.d.ts +2 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.js +6 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +8 -0
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.js +44 -1
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.d.ts +1 -0
- package/lib/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.js +3 -0
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.d.ts +21 -3
- package/lib/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.js +39 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.d.ts +20 -2
- package/lib/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.js +41 -2
- package/lib/src/shared/content-settings/utils.d.ts +1 -0
- package/lib/src/shared/content-settings/utils.js +6 -0
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +0 -1
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.js +0 -4
- package/package.json +2 -2
- package/src/brand-page/models/brand-page-context.model.ts +13 -3
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.ts +31 -0
- package/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.vue +2 -1
- package/src/brand-page-maker/stores/brandpage-container/brand-page-container-store.ts +0 -36
- package/src/brand-page-maker/stores/index.ts +1 -0
- package/src/brand-page-maker/stores/snapshot/snapshot-store.ts +31 -0
- package/src/brand-page-maker/utils/rich-text-editor.util.ts +154 -0
- package/src/bundles/bundled-translations.de-DE.json +15 -1
- package/src/bundles/bundled-translations.es-ES.json +15 -1
- package/src/bundles/bundled-translations.fr-CA.json +15 -1
- package/src/bundles/bundled-translations.fr-FR.json +15 -1
- package/src/bundles/bundled-translations.json +15 -1
- package/src/bundles/bundled-translations.pt-BR.json +15 -1
- package/src/bundles/bundled-translations.pt-PT.json +15 -1
- package/src/clients/brand-page-client.ts +0 -4
- package/src/clients/design-template-client.ts +57 -0
- package/src/composables/useSnapshot.ts +97 -0
- package/src/composables/useTranslate.ts +3 -0
- package/src/shared/common/i18n/common.de-DE.json +5 -1
- package/src/shared/common/i18n/common.es-ES.json +5 -1
- package/src/shared/common/i18n/common.fr-CA.json +5 -1
- package/src/shared/common/i18n/common.fr-FR.json +5 -1
- package/src/shared/common/i18n/common.json +5 -1
- package/src/shared/common/i18n/common.pt-BR.json +5 -1
- package/src/shared/common/i18n/common.pt-PT.json +5 -1
- package/src/shared/content-settings/components/content-settings/ContentSettings.mixin.ts +3 -0
- package/src/shared/content-settings/components/content-settings/ContentSettings.vue +2 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.mixin.ts +8 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItem.vue +1 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.ts +54 -0
- package/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.vue +20 -2
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.mixin.ts +3 -1
- package/src/shared/content-settings/components/focused-content-item-settings/FocusedContentItemSettings.vue +1 -0
- package/src/shared/content-settings/components/generate-ai-button/GenerateAiButton.vue +95 -0
- package/src/shared/content-settings/components/generate-ai-modal/GenerateAiModal.vue +500 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.de-DE.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.es-ES.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.fr-CA.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.fr-FR.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.pt-BR.json +12 -0
- package/src/shared/content-settings/components/generate-ai-modal/i18n/generate-ai.pt-PT.json +12 -0
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.mixin.ts +44 -2
- package/src/shared/content-settings/components/testimonial-items-field/TestimonialItemsField.vue +15 -3
- package/src/shared/content-settings/components/text-items-field/TextItemsField.mixin.ts +52 -2
- package/src/shared/content-settings/components/text-items-field/TextItemsField.vue +16 -3
- package/src/shared/content-settings/utils.ts +9 -0
- package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.ts +0 -6
- package/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.vue +1 -1
- package/lib/src/bundled-translations-D9iHE5G9.js +0 -161
- package/lib/src/bundled-translations.de-DE-DW3iDx_G.js +0 -161
- package/lib/src/bundled-translations.es-ES-C9I8wDyq.js +0 -161
- package/lib/src/bundled-translations.fr-CA-C0NN8DsO.js +0 -161
- package/lib/src/bundled-translations.fr-FR-oKV5NyE1.js +0 -161
- package/lib/src/bundled-translations.pt-BR-CTvCfv1X.js +0 -161
- package/lib/src/bundled-translations.pt-PT-CbwxwRY1.js +0 -161
|
@@ -36,7 +36,7 @@ export interface AbTestResult {
|
|
|
36
36
|
}
|
|
37
37
|
export interface AbTest {
|
|
38
38
|
bp_3926_freemium_watermark?: AbTestResult;
|
|
39
|
-
|
|
39
|
+
bp_4572_ai_text_generation_post_purchase?: AbTestResult;
|
|
40
40
|
}
|
|
41
41
|
export declare const MEDIA_SIZES: {
|
|
42
42
|
readonly size1x: "size1x";
|
|
@@ -24,7 +24,7 @@ export const AB_TEST_FLAG = {
|
|
|
24
24
|
};
|
|
25
25
|
const AB_TEST_KEYS = {
|
|
26
26
|
BP_3926_FREEMIUM_WATERMARK: 'bc-bp-3926-freemium-cta-in-website-editor',
|
|
27
|
-
|
|
27
|
+
BP_4572_AI_TEXT_GENERATION_POST_PURCHASE: 'bc-bp-4572-ai-text-generation-post-purchase',
|
|
28
28
|
};
|
|
29
29
|
export const MEDIA_SIZES = {
|
|
30
30
|
size1x: 'size1x',
|
|
@@ -46,5 +46,9 @@ export const getAbTestResults = (abtestKeyValues) => {
|
|
|
46
46
|
if (abtestKeyValues[AB_TEST_KEYS.BP_3926_FREEMIUM_WATERMARK]) {
|
|
47
47
|
abTests.bp_3926_freemium_watermark = getValueType(AB_TEST_KEYS.BP_3926_FREEMIUM_WATERMARK, abtestKeyValues[AB_TEST_KEYS.BP_3926_FREEMIUM_WATERMARK]);
|
|
48
48
|
}
|
|
49
|
+
// AB Test for BP-4572 - AI Text Generation Post Purchase
|
|
50
|
+
if (abtestKeyValues[AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE]) {
|
|
51
|
+
abTests.bp_4572_ai_text_generation_post_purchase = getValueType(AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE, abtestKeyValues[AB_TEST_KEYS.BP_4572_AI_TEXT_GENERATION_POST_PURCHASE]);
|
|
52
|
+
}
|
|
49
53
|
return abTests;
|
|
50
54
|
};
|
|
@@ -1146,6 +1146,17 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
1146
1146
|
getProductModel(): import("../../../brand-page/models/shop.model").ProductModel;
|
|
1147
1147
|
}>;
|
|
1148
1148
|
router: import("vue-router").Router;
|
|
1149
|
+
snapshotStore: import("pinia").Store<"snapshot", import("../../stores").SnapshotState, {
|
|
1150
|
+
hasSnapshot: (state: {
|
|
1151
|
+
snapshotBase64: string | null;
|
|
1152
|
+
isCapturing: boolean;
|
|
1153
|
+
} & import("pinia").PiniaCustomStateProperties<import("../../stores").SnapshotState>) => boolean;
|
|
1154
|
+
}, {
|
|
1155
|
+
setBase64Snapshot(base64: string | null): void;
|
|
1156
|
+
setIsCapturing(isCapturing: boolean): void;
|
|
1157
|
+
clearSnapshot(): void;
|
|
1158
|
+
}>;
|
|
1159
|
+
captureSnapshot: (element: HTMLElement | null) => Promise<string | null>;
|
|
1149
1160
|
videoStore: import("pinia").Store<"video", import("../../stores").videoStoreState, {
|
|
1150
1161
|
getVideoUrlsForToken: (state: {
|
|
1151
1162
|
videoUrls: {
|
|
@@ -1186,8 +1197,10 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
1186
1197
|
showSaveSuccessMessage: boolean;
|
|
1187
1198
|
}, {
|
|
1188
1199
|
previewContainer(): any;
|
|
1200
|
+
previewContent(): any;
|
|
1189
1201
|
}, {
|
|
1190
1202
|
getBrandPageFromFallback(viewModel: any): BrandPageData;
|
|
1203
|
+
handleCaptureSnapshot(): Promise<void>;
|
|
1191
1204
|
onResizeWithDebounce(): void;
|
|
1192
1205
|
onResize(): void;
|
|
1193
1206
|
setUiScreenSizeModeBasedOnDeviceWidth(): void;
|
|
@@ -10,7 +10,7 @@ import { createInitialBrandPage } from '../../models';
|
|
|
10
10
|
import { navigateToPageBySlug } from '../../routing';
|
|
11
11
|
import { useBrandPageContainerStore } from '../../stores';
|
|
12
12
|
import { UI_DEVICE_MODES, UI_SCREENSIZE_MODES, } from '../../../shared/models';
|
|
13
|
-
import { useBrandPageMakerStore, useBrandPageMakerUserStore, useLocalisedRouteStore, useUiStore, useVideoStore, } from '../../stores';
|
|
13
|
+
import { useBrandPageMakerStore, useBrandPageMakerUserStore, useLocalisedRouteStore, useUiStore, useSnapshotStore, useVideoStore, } from '../../stores';
|
|
14
14
|
import { useUiContentSettingsStore } from '../../../shared/content-settings/store';
|
|
15
15
|
import { useUiTemplateSettingsStore } from '../../../shared/template-settings/store';
|
|
16
16
|
import { useUiPageSettingsStore } from '../../../shared/page-settings/store';
|
|
@@ -21,6 +21,7 @@ import { useShopConfigStore } from '../../../shared/ecommerce-settings/store/sho
|
|
|
21
21
|
import { useProductConfigStore } from '../../../brand-page-maker/stores/product-config/product-config-store';
|
|
22
22
|
import { UPGRADE_CTA_LOCATIONS } from '../../composables/useEventTracker';
|
|
23
23
|
import { commonTr } from '../../../composables/useTranslate';
|
|
24
|
+
import { useSnapshot } from '../../../composables/useSnapshot';
|
|
24
25
|
const RESIZE_DEBOUNCE_WAIT_IN_MS = 100;
|
|
25
26
|
export default defineComponent({
|
|
26
27
|
props: {
|
|
@@ -42,6 +43,8 @@ export default defineComponent({
|
|
|
42
43
|
const productSettingStore = useProductConfigStore();
|
|
43
44
|
const router = useRouter();
|
|
44
45
|
const localisedRouteStore = useLocalisedRouteStore();
|
|
46
|
+
const snapshotStore = useSnapshotStore();
|
|
47
|
+
const { captureSnapshot } = useSnapshot();
|
|
45
48
|
const videoStore = useVideoStore();
|
|
46
49
|
return {
|
|
47
50
|
commonTr,
|
|
@@ -84,6 +87,8 @@ export default defineComponent({
|
|
|
84
87
|
shopSettingStore,
|
|
85
88
|
productSettingStore,
|
|
86
89
|
router,
|
|
90
|
+
snapshotStore,
|
|
91
|
+
captureSnapshot,
|
|
87
92
|
videoStore,
|
|
88
93
|
};
|
|
89
94
|
},
|
|
@@ -99,6 +104,9 @@ export default defineComponent({
|
|
|
99
104
|
previewContainer() {
|
|
100
105
|
return this.$refs.previewContainer;
|
|
101
106
|
},
|
|
107
|
+
previewContent() {
|
|
108
|
+
return this.$refs.previewContent;
|
|
109
|
+
},
|
|
102
110
|
},
|
|
103
111
|
async created() {
|
|
104
112
|
if (!this.viewModel?.logoDraftDesignAttributes?.logoTheme ||
|
|
@@ -213,6 +221,27 @@ export default defineComponent({
|
|
|
213
221
|
return createInitialBrandPage(viewModel.brandPageType);
|
|
214
222
|
}
|
|
215
223
|
},
|
|
224
|
+
async handleCaptureSnapshot() {
|
|
225
|
+
if (!this.previewContent) {
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
this.snapshotStore.setIsCapturing(true);
|
|
229
|
+
try {
|
|
230
|
+
const snapshot = await this.captureSnapshot(this.previewContent);
|
|
231
|
+
if (snapshot) {
|
|
232
|
+
this.snapshotStore.setBase64Snapshot(snapshot);
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
console.warn('⚠️ Snapshot capture returned null');
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
console.error('❌ Failed to capture snapshot:', error);
|
|
240
|
+
}
|
|
241
|
+
finally {
|
|
242
|
+
this.snapshotStore.setIsCapturing(false);
|
|
243
|
+
}
|
|
244
|
+
},
|
|
216
245
|
onResizeWithDebounce() {
|
|
217
246
|
if (this.debounceOnResize) {
|
|
218
247
|
this.debounceOnResize();
|
|
@@ -255,10 +255,6 @@ export const useBrandPageContainerStore = defineStore('brandPageContainer', {
|
|
|
255
255
|
if (!response) {
|
|
256
256
|
throw new Error('Failed to set brand page slug');
|
|
257
257
|
}
|
|
258
|
-
if (response.websiteUpsellAbTestKey) {
|
|
259
|
-
this.abTests.bp_4092_rotating_upsells_at_publish = getValueType(response.websiteUpsellAbTestKey, response.websiteUpsellAbTestValue);
|
|
260
|
-
eventTracker.sendExperimentStartedEvent(response.websiteUpsellAbTestKey, response.websiteUpsellAbTestValue);
|
|
261
|
-
}
|
|
262
258
|
if (response.status) {
|
|
263
259
|
await this.setBrandPageStatus(response.status);
|
|
264
260
|
}
|
|
@@ -357,10 +353,6 @@ export const useBrandPageContainerStore = defineStore('brandPageContainer', {
|
|
|
357
353
|
if (!response) {
|
|
358
354
|
throw new Error('Failed to set brand page slug');
|
|
359
355
|
}
|
|
360
|
-
if (response.websiteUpsellAbTestKey) {
|
|
361
|
-
this.abTests.bp_4092_rotating_upsells_at_publish = getValueType(response.websiteUpsellAbTestKey, response.websiteUpsellAbTestValue);
|
|
362
|
-
eventTracker.sendExperimentStartedEvent(response.websiteUpsellAbTestKey, response.websiteUpsellAbTestValue);
|
|
363
|
-
}
|
|
364
356
|
await brandPageClient.getBrandPageIsCustomDomainEnabledAsync(brandPageMakerStore.brandPageType, this.designDraftToken);
|
|
365
357
|
const updatedIsCustomDomainEnabled = await brandPageClient.updateBrandPageIsCustomDomainEnabledAsync(brandPageMakerStore.brandPageType, this.designDraftToken, true);
|
|
366
358
|
this.setBrandPageIsCustomDomainEnabled({
|
|
@@ -561,10 +553,6 @@ export const useBrandPageContainerStore = defineStore('brandPageContainer', {
|
|
|
561
553
|
if (!response) {
|
|
562
554
|
return false;
|
|
563
555
|
}
|
|
564
|
-
if (response.websiteUpsellAbTestKey) {
|
|
565
|
-
this.abTests.bp_4092_rotating_upsells_at_publish = getValueType(response.websiteUpsellAbTestKey, response.websiteUpsellAbTestValue);
|
|
566
|
-
eventTracker.sendExperimentStartedEvent(response.websiteUpsellAbTestKey, response.websiteUpsellAbTestValue);
|
|
567
|
-
}
|
|
568
556
|
if (this.brandPageStatus !== response.status) {
|
|
569
557
|
await this.setBrandPageStatus(response.status);
|
|
570
558
|
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface SnapshotState {
|
|
2
|
+
snapshotBase64: string | null;
|
|
3
|
+
isCapturing: boolean;
|
|
4
|
+
}
|
|
5
|
+
export declare const useSnapshotStore: import("pinia").StoreDefinition<"snapshot", SnapshotState, {
|
|
6
|
+
hasSnapshot: (state: {
|
|
7
|
+
snapshotBase64: string | null;
|
|
8
|
+
isCapturing: boolean;
|
|
9
|
+
} & import("pinia").PiniaCustomStateProperties<SnapshotState>) => boolean;
|
|
10
|
+
}, {
|
|
11
|
+
setBase64Snapshot(base64: string | null): void;
|
|
12
|
+
setIsCapturing(isCapturing: boolean): void;
|
|
13
|
+
clearSnapshot(): void;
|
|
14
|
+
}>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { defineStore } from 'pinia';
|
|
2
|
+
export const useSnapshotStore = defineStore('snapshot', {
|
|
3
|
+
state: () => ({
|
|
4
|
+
snapshotBase64: null,
|
|
5
|
+
isCapturing: false,
|
|
6
|
+
}),
|
|
7
|
+
actions: {
|
|
8
|
+
setBase64Snapshot(base64) {
|
|
9
|
+
this.snapshotBase64 = base64;
|
|
10
|
+
},
|
|
11
|
+
setIsCapturing(isCapturing) {
|
|
12
|
+
this.isCapturing = isCapturing;
|
|
13
|
+
},
|
|
14
|
+
clearSnapshot() {
|
|
15
|
+
this.snapshotBase64 = null;
|
|
16
|
+
},
|
|
17
|
+
},
|
|
18
|
+
getters: {
|
|
19
|
+
hasSnapshot: (state) => !!state.snapshotBase64,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
@@ -8,6 +8,8 @@ import { type DOMPurify } from 'dompurify';
|
|
|
8
8
|
export declare const isStyleChanged: (tr: Transaction) => boolean;
|
|
9
9
|
export declare const skipStyleDetection: (chain: ChainedCommands, marks?: Mark[]) => ChainedCommands;
|
|
10
10
|
export declare const hasRTEContent: (content: string) => boolean;
|
|
11
|
+
export declare const getPlainTextFromRTE: (content: string) => string;
|
|
12
|
+
export declare const replaceTextInRTE: (existingHtml: string, newText: string) => string;
|
|
11
13
|
export declare const transformToRTE: (uiPageSettingStore: PageSettingsState, externalEditor: Editor, uiStyleSettingsStore?: StyleSettingsState, newContent?: Content, type?: TextStyleType, newStyle?: TextStyleDeclaration) => void;
|
|
12
14
|
export declare const switchAllContentToRTE: (uiPageSettingStore: PageSettingsState, externalEditor: Editor, uiStyleSettingsStore?: StyleSettingsState) => void;
|
|
13
15
|
export declare const getUpdatedHTMLFromEditor: (externalEditor: Editor, contentText: string, newContentStyle: TextStyleDeclaration) => string;
|
|
@@ -121,6 +121,123 @@ export const hasRTEContent = (content) => {
|
|
|
121
121
|
const tagWrapRegex = /^<([A-Za-z][A-Za-z0-9-]*)\b[^>]*>[\s\S]*<\/\1>$/;
|
|
122
122
|
return tagWrapRegex.test(trimmed);
|
|
123
123
|
};
|
|
124
|
+
export const getPlainTextFromRTE = (content) => {
|
|
125
|
+
if (typeof content !== 'string') {
|
|
126
|
+
return '';
|
|
127
|
+
}
|
|
128
|
+
// Only strip HTML tags if the value contains HTML
|
|
129
|
+
if (hasRTEContent(content)) {
|
|
130
|
+
return content.replace(/<[^>]*>/g, '').trim();
|
|
131
|
+
}
|
|
132
|
+
return content.trim();
|
|
133
|
+
};
|
|
134
|
+
export const replaceTextInRTE = (existingHtml, newText) => {
|
|
135
|
+
if (!hasRTEContent(existingHtml)) {
|
|
136
|
+
return `<p>${newText}</p>`;
|
|
137
|
+
}
|
|
138
|
+
const tempDiv = document.createElement('div');
|
|
139
|
+
tempDiv.innerHTML = existingHtml;
|
|
140
|
+
const blockElement = tempDiv.querySelector('p, div, h1, h2, h3, h4, h5, h6, blockquote');
|
|
141
|
+
if (!blockElement) {
|
|
142
|
+
return `<p>${newText}</p>`;
|
|
143
|
+
}
|
|
144
|
+
// Collect all spans and their styles
|
|
145
|
+
const spans = blockElement.querySelectorAll('span');
|
|
146
|
+
const mergedStyles = {};
|
|
147
|
+
const hasFormatting = {
|
|
148
|
+
bold: false,
|
|
149
|
+
italic: false,
|
|
150
|
+
underline: false,
|
|
151
|
+
strikethrough: false,
|
|
152
|
+
mark: false,
|
|
153
|
+
markColor: '',
|
|
154
|
+
markStyle: '',
|
|
155
|
+
};
|
|
156
|
+
// Iterate through all spans to collect and merge styles
|
|
157
|
+
spans.forEach((span) => {
|
|
158
|
+
// Collect inline styles
|
|
159
|
+
if (span.style.cssText) {
|
|
160
|
+
const styleDeclarations = span.style.cssText.split(';');
|
|
161
|
+
styleDeclarations.forEach((declaration) => {
|
|
162
|
+
const [property, value] = declaration.split(':').map((s) => s.trim());
|
|
163
|
+
if (property && value) {
|
|
164
|
+
mergedStyles[property] = value; // Latest value overwrites previous
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
// Collect data attributes (like data-color for marks)
|
|
169
|
+
if (span.hasAttribute('data-color')) {
|
|
170
|
+
mergedStyles['data-color'] = span.getAttribute('data-color') || '';
|
|
171
|
+
}
|
|
172
|
+
// Check for formatting tags within this span
|
|
173
|
+
if (span.querySelector('strong, b'))
|
|
174
|
+
hasFormatting.bold = true;
|
|
175
|
+
if (span.querySelector('em, i'))
|
|
176
|
+
hasFormatting.italic = true;
|
|
177
|
+
if (span.querySelector('u'))
|
|
178
|
+
hasFormatting.underline = true;
|
|
179
|
+
if (span.querySelector('s, strike, del'))
|
|
180
|
+
hasFormatting.strikethrough = true;
|
|
181
|
+
// Check for mark/highlight tags
|
|
182
|
+
const markElement = span.querySelector('mark');
|
|
183
|
+
if (markElement) {
|
|
184
|
+
hasFormatting.mark = true;
|
|
185
|
+
if (markElement.hasAttribute('data-color')) {
|
|
186
|
+
hasFormatting.markColor = markElement.getAttribute('data-color') || '';
|
|
187
|
+
}
|
|
188
|
+
if (markElement.style.cssText) {
|
|
189
|
+
hasFormatting.markStyle = markElement.style.cssText;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
// Create the new span with merged styles
|
|
194
|
+
const newSpan = document.createElement('span');
|
|
195
|
+
// Apply collected inline styles
|
|
196
|
+
Object.entries(mergedStyles).forEach(([property, value]) => {
|
|
197
|
+
if (property === 'data-color') {
|
|
198
|
+
newSpan.setAttribute('data-color', value);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
newSpan.style.setProperty(property, value);
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
// Build the formatted text with nested tags
|
|
205
|
+
let formattedText = newText;
|
|
206
|
+
// Apply mark/highlight if present
|
|
207
|
+
if (hasFormatting.mark) {
|
|
208
|
+
const markElement = document.createElement('mark');
|
|
209
|
+
if (hasFormatting.markColor) {
|
|
210
|
+
markElement.setAttribute('data-color', hasFormatting.markColor);
|
|
211
|
+
}
|
|
212
|
+
if (hasFormatting.markStyle) {
|
|
213
|
+
markElement.style.cssText = hasFormatting.markStyle;
|
|
214
|
+
}
|
|
215
|
+
markElement.textContent = formattedText;
|
|
216
|
+
formattedText = markElement.outerHTML;
|
|
217
|
+
}
|
|
218
|
+
// Apply underline
|
|
219
|
+
if (hasFormatting.underline) {
|
|
220
|
+
formattedText = `<u>${formattedText}</u>`;
|
|
221
|
+
}
|
|
222
|
+
// Apply strikethrough
|
|
223
|
+
if (hasFormatting.strikethrough) {
|
|
224
|
+
formattedText = `<s>${formattedText}</s>`;
|
|
225
|
+
}
|
|
226
|
+
// Apply italic
|
|
227
|
+
if (hasFormatting.italic) {
|
|
228
|
+
formattedText = `<em>${formattedText}</em>`;
|
|
229
|
+
}
|
|
230
|
+
// Apply bold
|
|
231
|
+
if (hasFormatting.bold) {
|
|
232
|
+
formattedText = `<strong>${formattedText}</strong>`;
|
|
233
|
+
}
|
|
234
|
+
// Set the formatted content to the span
|
|
235
|
+
newSpan.innerHTML = formattedText;
|
|
236
|
+
// Clear the block element and add the new span
|
|
237
|
+
blockElement.innerHTML = '';
|
|
238
|
+
blockElement.appendChild(newSpan);
|
|
239
|
+
return tempDiv.innerHTML;
|
|
240
|
+
};
|
|
124
241
|
export const transformToRTE = (uiPageSettingStore, externalEditor, uiStyleSettingsStore, newContent, type, newStyle) => {
|
|
125
242
|
for (const page of uiPageSettingStore.pages) {
|
|
126
243
|
for (const contentItem of page.contents) {
|