@designcrowd/library.brand-page 5.18.1-undo-22 → 5.18.1-undo-23
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-AFaRM8AB.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-en-us-QDl7ywkQ.js → CreatedOnBrandCrowd-en-us-Hzq-a60h.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-es-es-DcbldLR8.js → CreatedOnBrandCrowd-es-es-JcJzcPt4.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-fr-CtKg-kmK.js → CreatedOnBrandCrowd-fr-ca-BvfD6_cT.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-fr-ca-CtKg-kmK.js → CreatedOnBrandCrowd-fr-fr-BvfD6_cT.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-pt-B8LdULlM.js → CreatedOnBrandCrowd-pt-br-CvCBHtHz.js} +1 -1
- package/lib/src/{CreatedOnBrandCrowd-pt-br-B8LdULlM.js → CreatedOnBrandCrowd-pt-pt-CvCBHtHz.js} +1 -1
- package/lib/src/{CreatedOnDcom-de-de-B8a5JB3V.js → CreatedOnDcom-de-de-DY72j1HT.js} +1 -1
- package/lib/src/{CreatedOnDcom-en-us-BxJb4VxH.js → CreatedOnDcom-en-us-CQlkVR3f.js} +1 -1
- package/lib/src/{CreatedOnDcom-es-es-_YCAGVL0.js → CreatedOnDcom-es-es-B308Qq0k.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-ca-DV5JKmY0.js → CreatedOnDcom-fr-ca-CmZfNZDD.js} +1 -1
- package/lib/src/{CreatedOnDcom-fr-fr-CjGeFt2Y.js → CreatedOnDcom-fr-fr-YEMbYuns.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-br-fPa9wQ6j.js → CreatedOnDcom-pt-br-DC06ZQTq.js} +1 -1
- package/lib/src/{CreatedOnDcom-pt-pt-BEC57JU6.js → CreatedOnDcom-pt-pt-gbUCpWPU.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 +71 -27
- package/lib/src/index.mjs +1 -1
- package/lib/src/{lib-BxlBHrQd.js → lib-gUHeBTLS.js} +8581 -8547
- 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 +240 -11
- package/src/brand-page-maker/stores/history/history-store.ts +97 -27
|
@@ -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,34 +312,49 @@ 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
|
}
|
|
311
359
|
function normalizeNode(node) {
|
|
312
360
|
if (Array.isArray(node))
|
|
@@ -321,17 +369,6 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
321
369
|
// represent a user-visible change.
|
|
322
370
|
if (key === 'isModifiedAfterTemplateApplied')
|
|
323
371
|
continue;
|
|
324
|
-
// Strip the rendered logo PNG. Logo property edits (text, color,
|
|
325
|
-
// font, outline, shadow) authored via the Logo sidebar live in
|
|
326
|
-
// `editableLogoStore.logoEdits` — which is NOT in `brandPageData`,
|
|
327
|
-
// so an undo would revert this base64 image on the canvas without
|
|
328
|
-
// touching the sidebar fields. Per V1 scope, logo property edits
|
|
329
|
-
// are non-undoable (parallels the PRD's admin-logo exclusion);
|
|
330
|
-
// BYO-upload undo still works because that change shows up in
|
|
331
|
-
// `logoImage.logoDraftToken`, not here. Stripping the field keeps
|
|
332
|
-
// those isolated render-output diffs out of the stack entirely.
|
|
333
|
-
if (key === 'logoImageBase64Url')
|
|
334
|
-
continue;
|
|
335
372
|
// Collapse RTE default-hydration wrappers down to the plain text
|
|
336
373
|
// they wrap. Plain "X" and `<p style="..."><span ...><mark ...>X
|
|
337
374
|
// </mark></span></p>` share the same canonical "X" so a sidebar
|
|
@@ -457,6 +494,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
457
494
|
label: args.label,
|
|
458
495
|
sizeBytes: args.snapshot.length,
|
|
459
496
|
activePageId: args.activePageId,
|
|
497
|
+
logoEdits: args.logoEdits,
|
|
460
498
|
};
|
|
461
499
|
// FR-11: truncate redo tail, then append.
|
|
462
500
|
const next = entries.value.slice(0, currentIndex.value + 1);
|
|
@@ -534,6 +572,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
534
572
|
if (!snapshot)
|
|
535
573
|
return;
|
|
536
574
|
const activePageId = getCurrentActivePageId();
|
|
575
|
+
const logoEdits = serializeCurrentLogoEdits();
|
|
537
576
|
// During the post-init settle window, fold any captured mutation back
|
|
538
577
|
// into the baseline (entry 0). Async cascades like template
|
|
539
578
|
// `loadPageNo`, the router's `afterEach`, and layout settling all
|
|
@@ -553,6 +592,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
553
592
|
timestamp: new Date().toISOString(),
|
|
554
593
|
sizeBytes: snapshot.length,
|
|
555
594
|
activePageId,
|
|
595
|
+
logoEdits,
|
|
556
596
|
},
|
|
557
597
|
];
|
|
558
598
|
return;
|
|
@@ -562,6 +602,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
562
602
|
source: 'manual_edit',
|
|
563
603
|
actor: 'user',
|
|
564
604
|
activePageId,
|
|
605
|
+
logoEdits,
|
|
565
606
|
});
|
|
566
607
|
};
|
|
567
608
|
// Monotonic burst arming. `isApplyingSnapshot` is gated here so an
|
|
@@ -606,6 +647,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
606
647
|
label: 'baseline',
|
|
607
648
|
sizeBytes: snapshot.length,
|
|
608
649
|
activePageId: getCurrentActivePageId(),
|
|
650
|
+
logoEdits: serializeCurrentLogoEdits(),
|
|
609
651
|
},
|
|
610
652
|
];
|
|
611
653
|
currentIndex.value = 0;
|
|
@@ -630,6 +672,7 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
630
672
|
return commitEntry({
|
|
631
673
|
snapshot,
|
|
632
674
|
activePageId: getCurrentActivePageId(),
|
|
675
|
+
logoEdits: serializeCurrentLogoEdits(),
|
|
633
676
|
...args,
|
|
634
677
|
});
|
|
635
678
|
}
|
|
@@ -725,9 +768,10 @@ export const useHistoryStore = defineStore('history', () => {
|
|
|
725
768
|
}
|
|
726
769
|
}
|
|
727
770
|
}
|
|
771
|
+
const targetEntry = entries.value[targetIndex];
|
|
728
772
|
isApplyingSnapshot.value = true;
|
|
729
773
|
try {
|
|
730
|
-
await brandPageMakerStore.applyHistorySnapshot(snapshot, resolvedActivePageId);
|
|
774
|
+
await brandPageMakerStore.applyHistorySnapshot(snapshot, resolvedActivePageId, targetEntry?.logoEdits);
|
|
731
775
|
await nextTick();
|
|
732
776
|
}
|
|
733
777
|
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-gUHeBTLS.js";
|
|
2
2
|
import { createPinia as wE, setActivePinia as ZE } from "pinia";
|
|
3
3
|
export {
|
|
4
4
|
E as ABOUT_SECTION_SETTINGS_CONFIG,
|