Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
68e62b6
feat: add page context helper for custom URL handling in Visual Builder
kirtesh-cstk May 21, 2026
15ab0c6
fix(VP-556): replace deprecated unload event with pagehide in page tr…
kirtesh-cstk May 25, 2026
fc2fcae
fix: added update to stop the double firing of init in vb
contentstackMridul May 25, 2026
c508c47
test: resolve test failure due to mock failure
contentstackMridul May 26, 2026
e747746
fix: fixed the sideEffect issue due to setConfigFromParams
contentstackMridul May 26, 2026
5b73339
test: added test cases for remaining live preivew and post message fu…
contentstackMridul May 26, 2026
d968e05
test: added remaining gap tests from VB-1504
contentstackMridul May 27, 2026
d3d2a09
Merge pull request #602 from contentstack/VB-1677
contentstackMridul May 29, 2026
a46d025
Merge pull request #600 from contentstack/VB-1667
contentstackMridul May 29, 2026
87648b9
Merge pull request #603 from contentstack/VB-1504_remaining_gaps
contentstackMridul Jun 3, 2026
682ade3
Merge branch 'develop_v4' into feat-add-page-context-helper-for-custo…
kirtesh-cstk Jun 8, 2026
7d28b7c
chore: remove erroneous expection line
kirtesh-cstk Jun 8, 2026
66a7802
fix: handle postMessage failures in setPageContext
kirtesh-cstk Jun 9, 2026
8225388
Merge pull request #605 from contentstack/feat-add-page-context-helpe…
kirtesh-cstk Jun 9, 2026
da52771
Merge pull request #599 from contentstack/VP-556-replace-deprecated-u…
kirtesh-cstk Jun 9, 2026
91c6c6e
fix: add missing expection in test while merging code
kirtesh-cstk Jun 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/common/inIframe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ export function inIframe(): boolean {
}
}

export function inVisualEditor(): boolean{
try {
return inIframe() && window?.name == 'visual-editor'
} catch (e) {
return false;
}
}

export function isOpeningInNewTab(): boolean {
try {
if(hasWindow()) {
Expand Down
69 changes: 68 additions & 1 deletion src/configManager/__test__/configManager.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Config, { updateConfigFromUrl } from "../configManager";
import Config, { updateConfigFromUrl, syncToStackSdk } from "../configManager";
import { getDefaultConfig, getUserInitData } from "../config.default";
import { DeepSignal } from "deepsignal";
import { IConfig } from "../../types/types";
Expand Down Expand Up @@ -102,6 +102,73 @@ describe("config default flags", () => {
});
});

describe("syncToStackSdk", () => {
beforeEach(() => {
Config.reset();
});

afterAll(() => {
Config.reset();
});

test("should set hash, stackSdkLivePreview.hash and stackSdkLivePreview.live_preview when hash is provided", () => {
syncToStackSdk({ hash: "abc123" });

const config = Config.get();
expect(config.stackSdk.live_preview.hash).toBe("abc123");
expect(config.stackSdk.live_preview.live_preview).toBe("abc123");
expect(config.stackSdk.live_preview.content_type_uid).toBeUndefined();
expect(config.stackSdk.live_preview.entry_uid).toBeUndefined();
});

test("should set content_type_uid on stackSdk when contentTypeUid is provided", () => {
syncToStackSdk({ contentTypeUid: "blog" });

const config = Config.get();
expect(config.stackSdk.live_preview.content_type_uid).toBe("blog");
expect(config.stackSdk.live_preview.hash).toBeUndefined();
expect(config.stackSdk.live_preview.entry_uid).toBeUndefined();
});

test("should set entry_uid on stackSdk when entryUid is provided", () => {
syncToStackSdk({ entryUid: "entry-42" });

const config = Config.get();
expect(config.stackSdk.live_preview.entry_uid).toBe("entry-42");
expect(config.stackSdk.live_preview.hash).toBeUndefined();
expect(config.stackSdk.live_preview.content_type_uid).toBeUndefined();
});

test("should set all three fields when all params are provided", () => {
syncToStackSdk({ hash: "h1", contentTypeUid: "page", entryUid: "e1" });

const config = Config.get();
expect(config.stackSdk.live_preview.hash).toBe("h1");
expect(config.stackSdk.live_preview.live_preview).toBe("h1");
expect(config.stackSdk.live_preview.content_type_uid).toBe("page");
expect(config.stackSdk.live_preview.entry_uid).toBe("e1");
});

test("should skip falsy values — null and undefined are ignored", () => {
syncToStackSdk({ hash: null, contentTypeUid: undefined, entryUid: null });

const config = Config.get();
expect(config.stackSdk.live_preview.hash).toBeUndefined();
expect(config.stackSdk.live_preview.content_type_uid).toBeUndefined();
expect(config.stackSdk.live_preview.entry_uid).toBeUndefined();
});

test("should not overwrite existing stackSdk values for keys not passed", () => {
syncToStackSdk({ hash: "first", contentTypeUid: "ct1", entryUid: "e1" });
syncToStackSdk({ hash: "second" });

const config = Config.get();
expect(config.stackSdk.live_preview.hash).toBe("second");
expect(config.stackSdk.live_preview.content_type_uid).toBe("ct1");
expect(config.stackSdk.live_preview.entry_uid).toBe("e1");
});
});

describe("update config from url", () => {
let config: DeepSignal<IConfig>;

Expand Down
1 change: 1 addition & 0 deletions src/configManager/config.default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,5 +118,6 @@ export function getDefaultConfig(): IConfig {
payload: [],
},
enableLivePreviewOutsideIframe: undefined,
pageContext: null,
};
}
40 changes: 34 additions & 6 deletions src/configManager/configManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,50 @@ export function setConfigFromParams(
const content_type_uid = urlParams.get("content_type_uid");
const entry_uid = urlParams.get("entry_uid");

const stackSdkLivePreview = Config.get().stackSdk.live_preview;

if (live_preview) {
Config.set("hash", live_preview);
stackSdkLivePreview.hash = live_preview;
stackSdkLivePreview.live_preview = live_preview;
}

if (content_type_uid) {
Config.set("stackDetails.contentTypeUid", content_type_uid);
stackSdkLivePreview.content_type_uid = content_type_uid;
}

if (entry_uid) {
Config.set("stackDetails.entryUid", entry_uid);
stackSdkLivePreview.entry_uid = entry_uid;
}

syncToStackSdk({
hash: live_preview,
contentTypeUid: content_type_uid,
entryUid: entry_uid,
});
}

/**
* Syncs hash, contentTypeUid, and entryUid into the user's stackSdk.live_preview object.
* Auto-effects via deepsignal were ruled out because Config.reset() replaces the deepSignal
* instance, which would blind any bound effect. Explicit sync is the safe alternative.
*/
export function syncToStackSdk({
hash,
contentTypeUid,
entryUid,
}: {
hash?: string | null;
contentTypeUid?: string | null;
entryUid?: string | null;
}): void {
const stackSdkLivePreview = Config.get().stackSdk.live_preview;

if (hash) {
stackSdkLivePreview.hash = hash;
stackSdkLivePreview.live_preview = hash;
}
if (contentTypeUid) {
stackSdkLivePreview.content_type_uid = contentTypeUid;
}
if (entryUid) {
stackSdkLivePreview.entry_uid = entryUid;
}

Config.set("stackSdk.live_preview", stackSdkLivePreview);
Expand Down
Loading
Loading