@designcrowd/library.brand-page 5.18.1-undo-22 → 5.18.1-undo-24
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-Q1oYxhFA.js → CreatedOnBrandCrowd-de-de-DKlq-FhR.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-QDl7ywkQ.js → CreatedOnBrandCrowd-en-us-CKuJf1eN.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-DcbldLR8.js → CreatedOnBrandCrowd-es-es-CDgHdsZn.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-CtKg-kmK.js → CreatedOnBrandCrowd-fr-ca-DKkek1Qq.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-CtKg-kmK.js → CreatedOnBrandCrowd-fr-fr-DKkek1Qq.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-B8LdULlM.js → CreatedOnBrandCrowd-pt-br-DtiYMB85.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-B8LdULlM.js → CreatedOnBrandCrowd-pt-pt-DtiYMB85.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-B8a5JB3V.js → CreatedOnDcom-de-de-DcipMp9e.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-BxJb4VxH.js → CreatedOnDcom-en-us-DUtpfMxY.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-_YCAGVL0.js → CreatedOnDcom-es-es-3sfbICpP.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-DV5JKmY0.js → CreatedOnDcom-fr-ca-Dot_vGyn.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-CjGeFt2Y.js → CreatedOnDcom-fr-fr-BFu2DRry.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-fPa9wQ6j.js → CreatedOnDcom-pt-br-CZD58a0R.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-BEC57JU6.js → CreatedOnDcom-pt-pt-DRMoU43s.js} +1 -1
- package/lib/src/brand-page-maker/components/action-bar/ActionBar.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMaker.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/brand-page-maker/BrandPageMakerTemplateSettings.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/brandpage-settings/ReplaceImageSettingsForBrandPageSettings.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/seo-settings/SeoPageSettings.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/seo-settings/UrlSettings.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/social-share/SocialShare.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/components/template-preview/TemplatePreview.mixin.d.ts +2 -2
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.d.ts +2 -2
- package/lib/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.js +33 -4
- package/lib/src/brand-page-maker/stores/history/history-store.d.ts +17 -1
- package/lib/src/brand-page-maker/stores/history/history-store.js +98 -27
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-BxlBHrQd.js → lib-tDiln44T.js} +9935 -9888
- package/lib/src/shared/content-settings/components/content-settings/ContentSettings.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/content-settings/ReplaceImageSettingsForContent.mixin.d.ts +2 -2
- package/lib/src/shared/content-settings/components/content-settings-item/ContentSettingsItemField.mixin.d.ts +2 -2
- package/lib/src/shared/logo-settings/components/LogoSettings.mixin.d.ts +2 -2
- package/lib/src/shared/page-settings/components/page-settings/PageSettings.mixin.d.ts +2 -2
- package/lib/src/shared/page-settings/components/page-settings-section-styles/PageSettingsSectionStyles.mixin.d.ts +2 -2
- package/lib/src/shared/publish-brand-page-with-state/PublishBrandPageModalWithState.mixin.d.ts +2 -2
- package/lib/src/shared/style-settings/components/StyleSettings.mixin.d.ts +2 -2
- package/package.json +1 -1
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.test.ts +169 -0
- package/src/brand-page-maker/stores/brandpage-maker/brandpage-maker-store.ts +40 -3
- package/src/brand-page-maker/stores/history/history-store.test.ts +381 -11
- package/src/brand-page-maker/stores/history/history-store.ts +129 -26
|
@@ -118,8 +118,8 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
118
118
|
content: TContent;
|
|
119
119
|
}>(payload: P): Promise<void>;
|
|
120
120
|
_captureTemplateSwitchIfEnabled(): void;
|
|
121
|
-
applyHistorySnapshot(snapshot: import("@brand-page/models").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
122
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page/models").BrandPageModel): void;
|
|
121
|
+
applyHistorySnapshot(snapshot: import("@brand-page/models").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
122
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page/models").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
123
123
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
124
124
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page/models").BrandPageModel): void;
|
|
125
125
|
export(): import("@brand-page/models").BrandPageModel;
|
|
@@ -163,8 +163,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
163
163
|
content: TContent;
|
|
164
164
|
}>(payload: P): Promise<void>;
|
|
165
165
|
_captureTemplateSwitchIfEnabled(): void;
|
|
166
|
-
applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
167
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel): void;
|
|
166
|
+
applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
167
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
168
168
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
169
169
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
|
|
170
170
|
export(): import("@brand-page").BrandPageModel;
|
|
@@ -107,8 +107,8 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
107
107
|
content: TContent;
|
|
108
108
|
}>(payload: P): Promise<void>;
|
|
109
109
|
_captureTemplateSwitchIfEnabled(): void;
|
|
110
|
-
applyHistorySnapshot(snapshot: import("../../../lib").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
111
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("../../../lib").BrandPageModel): void;
|
|
110
|
+
applyHistorySnapshot(snapshot: import("../../../lib").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
111
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("../../../lib").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
112
112
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
113
113
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../lib").BrandPageModel): void;
|
|
114
114
|
export(): import("../../../lib").BrandPageModel;
|
package/lib/src/brand-page-maker/components/brandpage-maker-page/BrandPageMakerPage.mixin.d.ts
CHANGED
|
@@ -613,8 +613,8 @@ declare const _default: import("vue").DefineComponent<{}, {
|
|
|
613
613
|
content: TContent;
|
|
614
614
|
}>(payload: P): Promise<void>;
|
|
615
615
|
_captureTemplateSwitchIfEnabled(): void;
|
|
616
|
-
applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
617
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel): void;
|
|
616
|
+
applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
617
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
618
618
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
619
619
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
|
|
620
620
|
export(): import("@brand-page").BrandPageModel;
|
|
@@ -113,8 +113,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
113
113
|
content: TContent;
|
|
114
114
|
}>(payload: P): Promise<void>;
|
|
115
115
|
_captureTemplateSwitchIfEnabled(): void;
|
|
116
|
-
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
117
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
116
|
+
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
117
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
118
118
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
119
119
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
120
120
|
export(): import("../../../brand-page").BrandPageModel;
|
|
@@ -391,8 +391,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
391
391
|
content: TContent;
|
|
392
392
|
}>(payload: P): Promise<void>;
|
|
393
393
|
_captureTemplateSwitchIfEnabled(): void;
|
|
394
|
-
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
395
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
394
|
+
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
395
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
396
396
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
397
397
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
398
398
|
export(): import("../../../brand-page").BrandPageModel;
|
|
@@ -392,8 +392,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
392
392
|
content: TContent;
|
|
393
393
|
}>(payload: P): Promise<void>;
|
|
394
394
|
_captureTemplateSwitchIfEnabled(): void;
|
|
395
|
-
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
396
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
395
|
+
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
396
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
397
397
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
398
398
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
399
399
|
export(): import("../../../brand-page").BrandPageModel;
|
|
@@ -123,8 +123,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
123
123
|
content: TContent;
|
|
124
124
|
}>(payload: P): Promise<void>;
|
|
125
125
|
_captureTemplateSwitchIfEnabled(): void;
|
|
126
|
-
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
127
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
126
|
+
applyHistorySnapshot(snapshot: import("../../../brand-page").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
127
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("../../../brand-page").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
128
128
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
129
129
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("../../../brand-page").BrandPageModel): void;
|
|
130
130
|
export(): import("../../../brand-page").BrandPageModel;
|
|
@@ -443,8 +443,8 @@ declare const _default: import("vue").DefineComponent<import("vue").ExtractPropT
|
|
|
443
443
|
content: TContent;
|
|
444
444
|
}>(payload: P): Promise<void>;
|
|
445
445
|
_captureTemplateSwitchIfEnabled(): void;
|
|
446
|
-
applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string | undefined): Promise<void>;
|
|
447
|
-
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel): void;
|
|
446
|
+
applyHistorySnapshot(snapshot: import("@brand-page").BrandPageModel, activePageId?: string | undefined, logoEditsStr?: string | undefined): Promise<void>;
|
|
447
|
+
_syncLogoSettingsFromSnapshot(snapshot: import("@brand-page").BrandPageModel, logoEditsStr?: string | undefined): void;
|
|
448
448
|
_navigateToActivePage(activePageId?: string | undefined): void;
|
|
449
449
|
_fallbackSidebarIfSelectedContentMissing(snapshot: import("@brand-page").BrandPageModel): void;
|
|
450
450
|
export(): import("@brand-page").BrandPageModel;
|
|
@@ -209,8 +209,8 @@ export declare const useBrandPageMakerStore: import("pinia").StoreDefinition<"br
|
|
|
209
209
|
* feature flag is on — see `BrandPageMaker.mixin.ts`).
|
|
210
210
|
*/
|
|
211
211
|
_captureTemplateSwitchIfEnabled(): void;
|
|
212
|
-
applyHistorySnapshot(snapshot: BrandPageModel, activePageId?: string): Promise<void>;
|
|
213
|
-
_syncLogoSettingsFromSnapshot(snapshot: BrandPageModel): void;
|
|
212
|
+
applyHistorySnapshot(snapshot: BrandPageModel, activePageId?: string, logoEditsStr?: string): Promise<void>;
|
|
213
|
+
_syncLogoSettingsFromSnapshot(snapshot: BrandPageModel, logoEditsStr?: string): void;
|
|
214
214
|
/**
|
|
215
215
|
* Restore the active page after a history apply. The id passed in is
|
|
216
216
|
* already validated against the restored nav by the history store; if
|
|
@@ -493,7 +493,7 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
493
493
|
return;
|
|
494
494
|
historyStore.captureTemplateSwitch();
|
|
495
495
|
},
|
|
496
|
-
async applyHistorySnapshot(snapshot, activePageId) {
|
|
496
|
+
async applyHistorySnapshot(snapshot, activePageId, logoEditsStr) {
|
|
497
497
|
const styleSettingsStore = useUiStyleSettingsStore();
|
|
498
498
|
const navigationStyleSettingsStore = useUiNavigationStyleSettingsStore();
|
|
499
499
|
const backgroundSettingsStore = useUiBackgroundSettingsStore();
|
|
@@ -579,8 +579,12 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
579
579
|
// "current logo" state — same pattern as `initialiseStoresByBrandPageModelAsync`.
|
|
580
580
|
// Also restores the variations grid + template asset for the
|
|
581
581
|
// snapshot's draft token (both are sidecars to `brandPageData` —
|
|
582
|
-
// BYO upload mutates them out of band).
|
|
583
|
-
|
|
582
|
+
// BYO upload mutates them out of band). When the captured entry
|
|
583
|
+
// carries a `logoEdits` sidecar (pre-purchase logo-tab edits —
|
|
584
|
+
// text, support text, logo colors, fonts), `editableLogoStore.logoEdits`
|
|
585
|
+
// is restored from that string so the sidebar form fields and the
|
|
586
|
+
// save-time fabric-render POST both pick up the pre-edit state.
|
|
587
|
+
this._syncLogoSettingsFromSnapshot(snapshot, logoEditsStr);
|
|
584
588
|
// 9. If the sidebar is editing a content item that no longer exists in
|
|
585
589
|
// the restored page, fall back to the Content tab so the user doesn't
|
|
586
590
|
// stare at a blank settings panel.
|
|
@@ -597,10 +601,27 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
597
601
|
// sidebar's `currentPage` getter silently falls back to page 0.
|
|
598
602
|
this._navigateToActivePage(activePageId);
|
|
599
603
|
},
|
|
600
|
-
_syncLogoSettingsFromSnapshot(snapshot) {
|
|
604
|
+
_syncLogoSettingsFromSnapshot(snapshot, logoEditsStr) {
|
|
601
605
|
const logoSettingsStore = useUiLogoSettingsStore();
|
|
602
606
|
const editableLogoStore = useUiEditableLogoStore();
|
|
603
607
|
const logoStore = useLogoStore();
|
|
608
|
+
// Restore `editableLogoStore.logoEdits` first — sidecar to `brandPageData`,
|
|
609
|
+
// captured per-entry. Wholesale-replace via `$patch` so a previous
|
|
610
|
+
// entry's textObjects/colors don't leak through (e.g. switching
|
|
611
|
+
// template A→B then undoing A's restored object set must NOT contain
|
|
612
|
+
// B's textObject ids). Failing parse is non-fatal; the logo tab will
|
|
613
|
+
// just keep showing whatever logoEdits state was already loaded —
|
|
614
|
+
// canvas + saved metadata still come from `brandPageData` + the
|
|
615
|
+
// save-time `updateMetadataAsync` round-trip.
|
|
616
|
+
if (logoEditsStr) {
|
|
617
|
+
try {
|
|
618
|
+
const parsed = JSON.parse(logoEditsStr);
|
|
619
|
+
editableLogoStore.$patch({ logoEdits: parsed });
|
|
620
|
+
}
|
|
621
|
+
catch (error) {
|
|
622
|
+
console.error('brandpage-maker-store: failed to restore logoEdits', error);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
604
625
|
const logoImage = snapshot.brandPageType === BRAND_PAGE_TYPES.default
|
|
605
626
|
? snapshot.pages?.[0]?.contents?.find((c) => c.type === 'logo')?.logoImage
|
|
606
627
|
: snapshot.pageHeaderDesktop?.logoImage;
|
|
@@ -654,6 +675,14 @@ export const useBrandPageMakerStore = defineStore('brandPageMaker', {
|
|
|
654
675
|
}
|
|
655
676
|
if (!targetPageId)
|
|
656
677
|
return;
|
|
678
|
+
// Skip both the Pinia write and the router push when the target page
|
|
679
|
+
// is already active. The router push fires `router.afterEach` even
|
|
680
|
+
// for same-page navigation, and BrandPageMaker.mixin's afterEach hook
|
|
681
|
+
// resets the content-settings modeStack — which would snap the
|
|
682
|
+
// sidebar back to the default Content tab on every undo/redo,
|
|
683
|
+
// regardless of whether the user was deep-editing a content item.
|
|
684
|
+
if (pageNavigationStore.activePageId === targetPageId)
|
|
685
|
+
return;
|
|
657
686
|
pageNavigationStore.setCurrentActivePage({ pageId: targetPageId });
|
|
658
687
|
navigateToPageByPageId(targetPageId);
|
|
659
688
|
},
|
|
@@ -13,7 +13,10 @@
|
|
|
13
13
|
* the Logo sidebar, the active `logoTemplateAsset`, the active
|
|
14
14
|
* `logoDraftToken`) is restored on undo by `_syncLogoSettingsFromSnapshot`
|
|
15
15
|
* via per-draft-token caches on the logo / editable-logo stores — keyed off
|
|
16
|
-
* `logoImage.logoDraftToken` which IS in the snapshot.
|
|
16
|
+
* `logoImage.logoDraftToken` which IS in the snapshot. Pre-purchase logo-tab
|
|
17
|
+
* property edits (text, support text, logo colors, font, outline, shadow)
|
|
18
|
+
* live on `editableLogoStore.logoEdits` and ride along on the `logoEdits`
|
|
19
|
+
* sidecar below.
|
|
17
20
|
*/
|
|
18
21
|
export interface HistoryEntry {
|
|
19
22
|
/** JSON.stringify(BrandPageModel) at the moment of capture. */
|
|
@@ -40,6 +43,19 @@ export interface HistoryEntry {
|
|
|
40
43
|
* first router push). Always a real id once the editor has settled.
|
|
41
44
|
*/
|
|
42
45
|
activePageId: string;
|
|
46
|
+
/**
|
|
47
|
+
* `JSON.stringify(editableLogoStore.logoEdits)` at the moment of capture.
|
|
48
|
+
* Sidecar — `logoEdits` is NOT part of `brandPageData` but its state
|
|
49
|
+
* (logo text, support text, logo colors, fonts, outlines, shadows) drives
|
|
50
|
+
* what the pre-purchase save path POSTs to fabric-render to regenerate
|
|
51
|
+
* the persisted draft metadata. Without restoring it on undo, save after
|
|
52
|
+
* an undo would re-derive metadata from the post-edit `logoEdits` and
|
|
53
|
+
* silently reapply the change the user just undid.
|
|
54
|
+
*
|
|
55
|
+
* Undefined for sessions where the editable-logo store has never been
|
|
56
|
+
* touched (no logo tab interaction yet) — restore is a no-op in that case.
|
|
57
|
+
*/
|
|
58
|
+
logoEdits?: string;
|
|
43
59
|
}
|
|
44
60
|
export declare const useHistoryStore: import("pinia").StoreDefinition<"history", Pick<{
|
|
45
61
|
entries: import("vue").ShallowRef<HistoryEntry[], HistoryEntry[]>;
|
|
@@ -4,6 +4,8 @@ import { useBrandPageMakerStore } from '../brandpage-maker/brandpage-maker-store
|
|
|
4
4
|
import { useAiWebsiteBuilderThreadStore } from '../ai-thread/ai-website-builder-thread-store';
|
|
5
5
|
import { useEventTracker } from '../../composables/useEventTracker';
|
|
6
6
|
import { usePageNavigationStore } from '@shared/page-navigation/store/page-navigation-store';
|
|
7
|
+
import { useUiEditableLogoStore } from '@shared/logo-settings/store/editable-logo-store';
|
|
8
|
+
import { ESCAPED_NEWLINE_CHARACTER } from '@src/constants/ui';
|
|
7
9
|
/**
|
|
8
10
|
* Single-stack history model with a pointer instead of two stacks.
|
|
9
11
|
*
|
|
@@ -94,6 +96,21 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
94
96
|
function getCurrentActivePageId() {
|
|
95
97
|
return usePageNavigationStore().activePageId ?? '';
|
|
96
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Serialize the current `editableLogoStore.logoEdits` as a sidecar to the
|
|
101
|
+
* snapshot — see `HistoryEntry.logoEdits`. Returns undefined when the
|
|
102
|
+
* editable-logo store hasn't initialized yet (no logo tab interaction).
|
|
103
|
+
*/
|
|
104
|
+
function serializeCurrentLogoEdits() {
|
|
105
|
+
try {
|
|
106
|
+
const editableLogoStore = useUiEditableLogoStore();
|
|
107
|
+
return JSON.stringify(toRaw(editableLogoStore.logoEdits));
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
console.error('history-store: failed to serialize logoEdits', error);
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
97
114
|
/**
|
|
98
115
|
* Normalize a snapshot for the dedup byte-compare. Strips/canonicalizes
|
|
99
116
|
* fields that get mutated by sidebar-open reactive cascades but aren't
|
|
@@ -109,6 +126,11 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
109
126
|
* to mirror the resolved `textStyle.fontWeight / fontStyle /
|
|
110
127
|
* textDecoration` (e.g. plain `"text"` →
|
|
111
128
|
* `<p>...<span>...<strong>text</strong></span></p>`).
|
|
129
|
+
* - TipTap rendering the codebase's URL-encoded newline
|
|
130
|
+
* (`ESCAPED_NEWLINE_CHARACTER` = `%0A`) as `<br>` on first hydration
|
|
131
|
+
* (e.g. plain `"A%0AB"` → `<p><span>A<br>B</span></p>`). Plain-side
|
|
132
|
+
* `%0A` is decoded to `\n` and attributeless `<br>` is collapsed to
|
|
133
|
+
* `\n` in `extractCanonicalText`, so the two sides converge.
|
|
112
134
|
* - Lazy hydration of `*Style` objects when a content settings panel —
|
|
113
135
|
* or section selection on the canvas — resolves `textStyleType` and
|
|
114
136
|
* writes the full resolved style (fontFamily, fontSize, color,
|
|
@@ -116,12 +138,16 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
116
138
|
* onto the model. The `textStyleType` itself is the authoring
|
|
117
139
|
* intent; the resolved keys are just cached values.
|
|
118
140
|
* - `isModifiedAfterTemplateApplied` flipping on first edit gesture.
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
124
|
-
*
|
|
141
|
+
*
|
|
142
|
+
* Note: `logoImageBase64Url` (the rendered logo PNG) is NOT stripped here.
|
|
143
|
+
* Pre-purchase logo-tab edits (text, support text, logo colors, fonts)
|
|
144
|
+
* land in `editableLogoStore.logoEdits` (sidecar — see
|
|
145
|
+
* `HistoryEntry.logoEdits`) AND trigger a fabric-render that writes the
|
|
146
|
+
* new base64 into `pageHeaderDesktop.logoImageBase64Url` + per-page
|
|
147
|
+
* logo content. The base64 IS the canonical signal that a logo edit
|
|
148
|
+
* happened; stripping it would dedup real logo edits as no-ops. The
|
|
149
|
+
* 2-second `BASELINE_SETTLE_MS` window already collapses initial-load
|
|
150
|
+
* base64 churn into the baseline.
|
|
125
151
|
*
|
|
126
152
|
* RTE strings are canonicalized by parsing the HTML with DOMParser and
|
|
127
153
|
* walking the tree; only attributeless format wrappers (and a tightly
|
|
@@ -243,6 +269,13 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
243
269
|
return null;
|
|
244
270
|
}
|
|
245
271
|
const el = node;
|
|
272
|
+
// Attributeless <br> is TipTap's deterministic emission of a hard break.
|
|
273
|
+
// Treated as `\n` so a hydrated `<p><span>A<br>B</span></p>` canonicalizes
|
|
274
|
+
// to `"A\nB"` and matches the plain-side `"A%0AB"` after newline decoding.
|
|
275
|
+
// <br> with any attribute (e.g. `<br data-x>`) bails as before.
|
|
276
|
+
if (el.tagName === 'BR') {
|
|
277
|
+
return el.attributes.length === 0 ? '\n' : null;
|
|
278
|
+
}
|
|
246
279
|
const isStructural = STRUCTURAL_HYDRATION_TAGS.has(el.tagName);
|
|
247
280
|
const isFormat = FORMAT_HYDRATION_TAGS.has(el.tagName);
|
|
248
281
|
if (!isStructural && !isFormat)
|
|
@@ -279,35 +312,60 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
279
312
|
* once and writes back wrapped HTML with no user-visible delta.
|
|
280
313
|
*/
|
|
281
314
|
function canonicalizeRteString(value) {
|
|
282
|
-
//
|
|
315
|
+
// Decode the codebase's URL-encoded newline (`%0A` — see
|
|
316
|
+
// `ESCAPED_NEWLINE_CHARACTER`) on the plain-text side. The hydrated side
|
|
317
|
+
// emits `<br>` for the same logical newline, and `extractCanonicalText`
|
|
318
|
+
// collapses attributeless `<br>` to `\n`, so the two converge.
|
|
319
|
+
// `split`/`join` rather than `decodeURIComponent` keeps this narrow —
|
|
320
|
+
// we don't want to decode `%20`, `%3C`, etc., which would change real
|
|
321
|
+
// user content.
|
|
322
|
+
const decodeNewlines = (s) => s.split(ESCAPED_NEWLINE_CHARACTER).join('\n');
|
|
323
|
+
// Cheap exit: no tags at all. Still decode `%0A` so a plain-text entry
|
|
324
|
+
// matches a hydrated entry whose only diff is `<br>`-vs-newline.
|
|
283
325
|
if (!value.includes('<'))
|
|
284
|
-
return value;
|
|
326
|
+
return decodeNewlines(value);
|
|
285
327
|
if (isEmptyRteHtml(value))
|
|
286
328
|
return '';
|
|
287
329
|
// DOMParser is unavailable in some non-browser test environments;
|
|
288
330
|
// fall back to leaving the value as-is so the caller produces a
|
|
289
331
|
// real diff (i.e. fail open — never falsely collapse).
|
|
290
332
|
if (typeof DOMParser === 'undefined')
|
|
291
|
-
return value;
|
|
333
|
+
return decodeNewlines(value);
|
|
292
334
|
let doc;
|
|
293
335
|
try {
|
|
294
336
|
doc = new DOMParser().parseFromString(`<div id="__rte_root__">${value}</div>`, 'text/html');
|
|
295
337
|
}
|
|
296
338
|
catch {
|
|
297
|
-
return value;
|
|
339
|
+
return decodeNewlines(value);
|
|
298
340
|
}
|
|
299
341
|
const root = doc.getElementById('__rte_root__');
|
|
300
342
|
if (!root)
|
|
301
|
-
return value;
|
|
302
|
-
|
|
343
|
+
return decodeNewlines(value);
|
|
344
|
+
// Join top-level blocks with `\n`. TipTap renders an Enter keypress as
|
|
345
|
+
// a new top-level `<p>` sibling — without the join, `<p>Hello</p>` and
|
|
346
|
+
// `<p>Hello</p><p></p>` (or `<p>Hello</p><p>World</p>`) collapse to the
|
|
347
|
+
// same canonical text and the Enter is invisible to dedup. The join
|
|
348
|
+
// also matches plain-side `%0A` between paragraphs (e.g. stored
|
|
349
|
+
// `Hello%0AWorld` ↔ hydrated `<p>Hello</p><p>World</p>`).
|
|
350
|
+
const parts = [];
|
|
303
351
|
for (const child of Array.from(root.childNodes)) {
|
|
304
352
|
const part = extractCanonicalText(child);
|
|
305
353
|
if (part === null)
|
|
306
|
-
return value;
|
|
307
|
-
|
|
354
|
+
return decodeNewlines(value);
|
|
355
|
+
parts.push(part);
|
|
308
356
|
}
|
|
309
|
-
return
|
|
357
|
+
return parts.join('\n');
|
|
310
358
|
}
|
|
359
|
+
// Wrapper keys whose `paymentConfig` child is a denormalised cache of
|
|
360
|
+
// `shopConfigStore.paymentConfig` (the user's Stripe Connect linkage).
|
|
361
|
+
// The cache is hydrated lazily by `PaymentConfigField.mixin.ts:created()`
|
|
362
|
+
// when the user clicks into one of these sections — that hydration is
|
|
363
|
+
// not user authoring intent and must not produce a phantom undo entry.
|
|
364
|
+
const PAYMENT_CONFIG_WRAPPER_KEYS = new Set([
|
|
365
|
+
'supportMeConfig',
|
|
366
|
+
'requestPaymentConfig',
|
|
367
|
+
'shopPaymentConfig',
|
|
368
|
+
]);
|
|
311
369
|
function normalizeNode(node) {
|
|
312
370
|
if (Array.isArray(node))
|
|
313
371
|
return node.map(normalizeNode);
|
|
@@ -321,17 +379,23 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
321
379
|
// represent a user-visible change.
|
|
322
380
|
if (key === 'isModifiedAfterTemplateApplied')
|
|
323
381
|
continue;
|
|
324
|
-
// Strip
|
|
325
|
-
//
|
|
326
|
-
//
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
382
|
+
// Strip lazily-hydrated `paymentConfig` from payment-config wrappers
|
|
383
|
+
// (`supportMeConfig` / `requestPaymentConfig` / `shopPaymentConfig`)
|
|
384
|
+
// for the dedup compare. See `PAYMENT_CONFIG_WRAPPER_KEYS` above.
|
|
385
|
+
if (PAYMENT_CONFIG_WRAPPER_KEYS.has(key) &&
|
|
386
|
+
v !== null &&
|
|
387
|
+
typeof v === 'object' &&
|
|
388
|
+
!Array.isArray(v) &&
|
|
389
|
+
'paymentConfig' in v) {
|
|
390
|
+
const wrapper = v;
|
|
391
|
+
const stripped = {};
|
|
392
|
+
for (const k of Object.keys(wrapper)) {
|
|
393
|
+
if (k === 'paymentConfig')
|
|
394
|
+
continue;
|
|
395
|
+
stripped[k] = wrapper[k];
|
|
396
|
+
}
|
|
397
|
+
v = stripped;
|
|
398
|
+
}
|
|
335
399
|
// Collapse RTE default-hydration wrappers down to the plain text
|
|
336
400
|
// they wrap. Plain "X" and `<p style="..."><span ...><mark ...>X
|
|
337
401
|
// </mark></span></p>` share the same canonical "X" so a sidebar
|
|
@@ -457,6 +521,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
457
521
|
label: args.label,
|
|
458
522
|
sizeBytes: args.snapshot.length,
|
|
459
523
|
activePageId: args.activePageId,
|
|
524
|
+
logoEdits: args.logoEdits,
|
|
460
525
|
};
|
|
461
526
|
// FR-11: truncate redo tail, then append.
|
|
462
527
|
const next = entries.value.slice(0, currentIndex.value + 1);
|
|
@@ -534,6 +599,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
534
599
|
if (!snapshot)
|
|
535
600
|
return;
|
|
536
601
|
const activePageId = getCurrentActivePageId();
|
|
602
|
+
const logoEdits = serializeCurrentLogoEdits();
|
|
537
603
|
// During the post-init settle window, fold any captured mutation back
|
|
538
604
|
// into the baseline (entry 0). Async cascades like template
|
|
539
605
|
// `loadPageNo`, the router's `afterEach`, and layout settling all
|
|
@@ -553,6 +619,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
553
619
|
timestamp: new Date().toISOString(),
|
|
554
620
|
sizeBytes: snapshot.length,
|
|
555
621
|
activePageId,
|
|
622
|
+
logoEdits,
|
|
556
623
|
},
|
|
557
624
|
];
|
|
558
625
|
return;
|
|
@@ -562,6 +629,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
562
629
|
source: 'manual_edit',
|
|
563
630
|
actor: 'user',
|
|
564
631
|
activePageId,
|
|
632
|
+
logoEdits,
|
|
565
633
|
});
|
|
566
634
|
};
|
|
567
635
|
// Monotonic burst arming. `isApplyingSnapshot` is gated here so an
|
|
@@ -606,6 +674,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
606
674
|
label: 'baseline',
|
|
607
675
|
sizeBytes: snapshot.length,
|
|
608
676
|
activePageId: getCurrentActivePageId(),
|
|
677
|
+
logoEdits: serializeCurrentLogoEdits(),
|
|
609
678
|
},
|
|
610
679
|
];
|
|
611
680
|
currentIndex.value = 0;
|
|
@@ -630,6 +699,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
630
699
|
return commitEntry({
|
|
631
700
|
snapshot,
|
|
632
701
|
activePageId: getCurrentActivePageId(),
|
|
702
|
+
logoEdits: serializeCurrentLogoEdits(),
|
|
633
703
|
...args,
|
|
634
704
|
});
|
|
635
705
|
}
|
|
@@ -725,9 +795,10 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
725
795
|
}
|
|
726
796
|
}
|
|
727
797
|
}
|
|
798
|
+
const targetEntry = entries.value[targetIndex];
|
|
728
799
|
isApplyingSnapshot.value = true;
|
|
729
800
|
try {
|
|
730
|
-
await brandPageMakerStore.applyHistorySnapshot(snapshot, resolvedActivePageId);
|
|
801
|
+
await brandPageMakerStore.applyHistorySnapshot(snapshot, resolvedActivePageId, targetEntry?.logoEdits);
|
|
731
802
|
await nextTick();
|
|
732
803
|
}
|
|
733
804
|
finally {
|
package/lib/src/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as E, a as T, b as s, c as I, d as S, e as N, f as e, B as A, g as O, h as C, i as G, j as D, k as P, l as t, m as R, n as L, o as M, p as o, q as r, r as b, s as n, t as F, u as i, v as l, w as g, x as B, y as c, z as Y, C as U, D as d, E as u, F as H, G as p, H as y, I as K, J as k, K as m, L as V, M as X, N as h, O as v, P as W, Q as f, R as x, S as z, T as w, U as Z, V as j, W as Q, X as q, Y as J, Z as $, $ as aa, a0 as _a, a1 as Ea, a2 as Ta, a3 as sa, a4 as Ia, a5 as Sa, a6 as Na, a7 as ea, a8 as Aa, a9 as Oa, aa as Ca, ab as Ga, ac as Da, ad as Pa, ae as ta, af as Ra, ag as La, ah as Ma, ai as oa, aj as ra, ak as ba, al as na, am as Fa, an as ia, ao as la, ap as ga, aq as Ba, ar as ca, as as Ya, at as Ua, au as da, av as ua, aw as Ha, ax as pa, ay as ya, az as Ka, aA as ka, aB as ma, aC as Va, aD as Xa, aE as ha, aF as va, aG as Wa, aH as fa, aI as xa, aJ as za, aK as wa, aL as Za, aM as ja, aN as Qa, aO as qa, aP as Ja, aQ as $a, aR as a_, aS as __, aT as E_, aU as T_, aV as s_, aW as I_, aX as S_, aY as N_, aZ as e_, a_ as A_, a$ as O_, b0 as C_, b1 as G_, b2 as D_, b3 as P_, b4 as t_, b5 as R_, b6 as L_, b7 as M_, b8 as o_, b9 as r_, ba as b_, bb as n_, bc as F_, bd as i_, be as l_, bf as g_, bg as B_, bh as c_, bi as Y_, bj as U_, bk as d_, bl as u_, bm as H_, bn as p_, bo as y_, bp as K_, bq as k_, br as m_, bs as V_, bt as X_, bu as h_, bv as v_, bw as W_, bx as f_, by as x_, bz as z_, bA as w_, bB as Z_, bC as j_, bD as Q_, bE as q_, bF as J_, bG as $_, bH as aE, bI as _E, bJ as EE, bK as TE, bL as sE, bM as IE, bN as SE, bO as NE, bP as eE, bQ as AE, bR as OE, bS as CE, bT as GE, bU as DE, bV as PE, bW as tE, bX as RE, bY as LE, bZ as ME, b_ as oE, b$ as rE, c0 as bE, c1 as nE, c2 as FE, c3 as iE, c4 as lE, c5 as gE, c6 as BE, c7 as cE, c8 as YE, c9 as UE, ca as dE, cb as uE, cc as HE, cd as pE, ce as yE, cf as KE, cg as kE, ch as mE, ci as VE, cj as XE, ck as hE, cl as vE, cm as WE, cn as fE, co as xE } from "./lib-
|
|
1
|
+
import { A as E, a as T, b as s, c as I, d as S, e as N, f as e, B as A, g as O, h as C, i as G, j as D, k as P, l as t, m as R, n as L, o as M, p as o, q as r, r as b, s as n, t as F, u as i, v as l, w as g, x as B, y as c, z as Y, C as U, D as d, E as u, F as H, G as p, H as y, I as K, J as k, K as m, L as V, M as X, N as h, O as v, P as W, Q as f, R as x, S as z, T as w, U as Z, V as j, W as Q, X as q, Y as J, Z as $, $ as aa, a0 as _a, a1 as Ea, a2 as Ta, a3 as sa, a4 as Ia, a5 as Sa, a6 as Na, a7 as ea, a8 as Aa, a9 as Oa, aa as Ca, ab as Ga, ac as Da, ad as Pa, ae as ta, af as Ra, ag as La, ah as Ma, ai as oa, aj as ra, ak as ba, al as na, am as Fa, an as ia, ao as la, ap as ga, aq as Ba, ar as ca, as as Ya, at as Ua, au as da, av as ua, aw as Ha, ax as pa, ay as ya, az as Ka, aA as ka, aB as ma, aC as Va, aD as Xa, aE as ha, aF as va, aG as Wa, aH as fa, aI as xa, aJ as za, aK as wa, aL as Za, aM as ja, aN as Qa, aO as qa, aP as Ja, aQ as $a, aR as a_, aS as __, aT as E_, aU as T_, aV as s_, aW as I_, aX as S_, aY as N_, aZ as e_, a_ as A_, a$ as O_, b0 as C_, b1 as G_, b2 as D_, b3 as P_, b4 as t_, b5 as R_, b6 as L_, b7 as M_, b8 as o_, b9 as r_, ba as b_, bb as n_, bc as F_, bd as i_, be as l_, bf as g_, bg as B_, bh as c_, bi as Y_, bj as U_, bk as d_, bl as u_, bm as H_, bn as p_, bo as y_, bp as K_, bq as k_, br as m_, bs as V_, bt as X_, bu as h_, bv as v_, bw as W_, bx as f_, by as x_, bz as z_, bA as w_, bB as Z_, bC as j_, bD as Q_, bE as q_, bF as J_, bG as $_, bH as aE, bI as _E, bJ as EE, bK as TE, bL as sE, bM as IE, bN as SE, bO as NE, bP as eE, bQ as AE, bR as OE, bS as CE, bT as GE, bU as DE, bV as PE, bW as tE, bX as RE, bY as LE, bZ as ME, b_ as oE, b$ as rE, c0 as bE, c1 as nE, c2 as FE, c3 as iE, c4 as lE, c5 as gE, c6 as BE, c7 as cE, c8 as YE, c9 as UE, ca as dE, cb as uE, cc as HE, cd as pE, ce as yE, cf as KE, cg as kE, ch as mE, ci as VE, cj as XE, ck as hE, cl as vE, cm as WE, cn as fE, co as xE } from "./lib-tDiln44T.js";
|
|
2
2
|
import { createPinia as wE, setActivePinia as ZE } from "pinia";
|
|
3
3
|
export {
|
|
4
4
|
E as ABOUT_SECTION_SETTINGS_CONFIG,
|