Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -598,7 +598,7 @@ describe("cslp tooltip", () => {
});
new LivePreview();

let tooltip = document.querySelector(
const tooltip = document.querySelector(
"[data-test-id='cs-cslp-tooltip']"
);
const tooltipParent = tooltip?.parentNode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ describe("Live Preview HOC init", () => {
expect(livePreviewPostMessageSpy).toHaveBeenCalledTimes(1);
expect(visualBuilderPostMessageSpy).toHaveBeenCalledWith('init', { isSSR: true, href: 'http://localhost:3000/' });
expect(visualBuilderPostMessageSpy).toHaveBeenCalledWith('send-variant-and-locale');
expect(visualBuilderPostMessageSpy).toHaveBeenCalledTimes(2);
expect(visualBuilderPostMessageSpy).toHaveBeenCalledWith('get-highlight-variant-fields-status');
expect(visualBuilderPostMessageSpy).toHaveBeenCalledTimes(3);
});

test("should return the existing live preview instance if it is already initialized", async () => {
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import livePreviewPostMessage from "../../livePreview/eventManager/livePreviewEv
import { LIVE_PREVIEW_POST_MESSAGE_EVENTS } from "../../livePreview/eventManager/livePreviewEventManager.constant";
import { DATA_CSLP_ATTR_SELECTOR } from "../utils/constants";
import { visualBuilderStyles } from "../visualBuilder.style";
import { setHighlightVariantFields } from "./useVariantsPostMessageEvent";

const VARIANT_UPDATE_DELAY_MS: Readonly<number> = 8000;

Expand All @@ -19,15 +20,14 @@ export function useRecalculateVariantDataCSLPValues(): void {
LIVE_PREVIEW_POST_MESSAGE_EVENTS.VARIANT_PATCH,
(event) => {
if (VisualBuilder.VisualBuilderGlobalState.value.audienceMode) {
updateVariantClasses(event.data);
setHighlightVariantFields(event.data.highlightVariantFields);
updateVariantClasses();
}
}
);
}
function updateVariantClasses({
highlightVariantFields,
expectedCSLPValues,
}: OnAudienceModeVariantPatchUpdate): void {
export function updateVariantClasses(): void {
const highlightVariantFields = VisualBuilder.VisualBuilderGlobalState.value.highlightVariantFields;
const variant = VisualBuilder.VisualBuilderGlobalState.value.variant;
const observers: MutationObserver[] = [];

Expand All @@ -46,20 +46,17 @@ function updateVariantClasses({
if (element.classList.contains("visual-builder__base-field")) {
element.classList.remove("visual-builder__base-field");
}
const variantFieldClasses = ["visual-builder__variant-field"];
if (highlightVariantFields) {
element.classList.add(
visualBuilderStyles()["visual-builder__variant-field"],
"visual-builder__variant-field"
);
} else {
element.classList.add("visual-builder__variant-field");
variantFieldClasses.push(visualBuilderStyles()["visual-builder__variant-field-outline"]);
}
element.classList.add(...variantFieldClasses);
} else if (
!dataCslp.startsWith("v2:") &&
element.classList.contains("visual-builder__variant-field")
) {
element.classList.remove(
visualBuilderStyles()["visual-builder__variant-field"],
visualBuilderStyles()["visual-builder__variant-field-outline"],
"visual-builder__variant-field"
);
element.classList.add("visual-builder__base-field");
Expand All @@ -70,7 +67,7 @@ function updateVariantClasses({
element.classList.contains("visual-builder__variant-field")
) {
element.classList.remove(
visualBuilderStyles()["visual-builder__variant-field"],
visualBuilderStyles()["visual-builder__variant-field-outline"],
"visual-builder__variant-field"
);
element.classList.add("visual-builder__disabled-variant-field");
Expand Down Expand Up @@ -111,18 +108,15 @@ function updateVariantClasses({
if (element.classList.contains("visual-builder__base-field")) {
element.classList.remove("visual-builder__base-field");
}
const variantFieldClasses = ["visual-builder__variant-field"];
if (highlightVariantFields) {
element.classList.add(
visualBuilderStyles()["visual-builder__variant-field"],
"visual-builder__variant-field"
);
} else {
element.classList.add("visual-builder__variant-field");
variantFieldClasses.push(visualBuilderStyles()["visual-builder__variant-field-outline"]);
}
element.classList.add(...variantFieldClasses);
} else if (!dataCslp.startsWith("v2:")) {
if (element.classList.contains("visual-builder__variant-field")) {
element.classList.remove(
visualBuilderStyles()["visual-builder__variant-field"],
visualBuilderStyles()["visual-builder__variant-field-outline"],
"visual-builder__variant-field"
);
}
Expand Down Expand Up @@ -166,6 +160,7 @@ function updateVariantClasses({
});

observers.push(observer);
// TODO: Check if we could add attributeFilter to the observer to only observe the attribute changes for the data-cslp attribute.
observer.observe(element, {
attributes: true,
childList: true, // Observe direct children
Expand Down
69 changes: 59 additions & 10 deletions src/visualBuilder/eventManager/useVariantsPostMessageEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { visualBuilderStyles } from "../visualBuilder.style";
import visualBuilderPostMessage from "../utils/visualBuilderPostMessage";
import { VisualBuilderPostMessageEvents } from "../utils/types/postMessage.types";
import { FieldSchemaMap } from "../utils/fieldSchemaMap";
import { updateVariantClasses } from "./useRecalculateVariantDataCSLPValues";
import { debounce } from "lodash-es";
import { extractDetailsFromCslp } from "../../cslp/cslpdata";

interface VariantFieldsEvent {
Expand Down Expand Up @@ -50,22 +52,24 @@ function isLowerOrderVariant(variant_uid: string, dataCslp: string, variantOrder
return indexOfCslpVariant < indexOfCmsVariant;
}


export function addVariantFieldClass(
variant_uid: string,
highlightVariantFields: boolean,
variantOrder: string[]
): void {
const highlightVariantFields = VisualBuilder.VisualBuilderGlobalState.value.highlightVariantFields;
const elements = document.querySelectorAll(`[data-cslp]`);
elements.forEach((element) => {
const dataCslp = element.getAttribute("data-cslp");
if (!dataCslp) return;

if (dataCslp?.includes(variant_uid)) {
highlightVariantFields &&
element.classList.add("visual-builder__variant-field");
if (highlightVariantFields) {
element.classList.add(
visualBuilderStyles()["visual-builder__variant-field"]
visualBuilderStyles()["visual-builder__variant-field-outline"]
);
element.classList.add("visual-builder__variant-field");
}
} else if (!dataCslp.startsWith("v2:")) {
element.classList.add("visual-builder__base-field");
}
Expand All @@ -78,16 +82,25 @@ export function addVariantFieldClass(
});
}

export const debounceAddVariantFieldClass = debounce(
(variant_uid: string): void => {
const variantOrder = VisualBuilder.VisualBuilderGlobalState.value.variantOrder;
addVariantFieldClass(variant_uid, variantOrder);
},
1000,
{ trailing: true }
) as (variant_uid: string) => void;

export function removeVariantFieldClass(
onlyHighlighted: boolean = false
): void {
if (onlyHighlighted) {
const variantElements = document.querySelectorAll(
`.${visualBuilderStyles()["visual-builder__variant-field"]}`
`.${visualBuilderStyles()["visual-builder__variant-field-outline"]}`
);
variantElements.forEach((element) => {
element.classList.remove(
visualBuilderStyles()["visual-builder__variant-field"]
visualBuilderStyles()["visual-builder__variant-field-outline"]
);
});
} else {
Expand All @@ -98,7 +111,7 @@ export function removeVariantFieldClass(
element.classList.remove(
"visual-builder__disabled-variant-field",
"visual-builder__variant-field",
visualBuilderStyles()["visual-builder__variant-field"],
visualBuilderStyles()["visual-builder__variant-field-outline"],
"visual-builder__base-field",
"visual-builder__lower-order-variant-field"
);
Expand All @@ -115,18 +128,53 @@ export function setVariant(uid: string | null): void {
export function setLocale(locale: string): void {
VisualBuilder.VisualBuilderGlobalState.value.locale = locale;
}
export function setHighlightVariantFields(highlight: boolean): void {
VisualBuilder.VisualBuilderGlobalState.value.highlightVariantFields = highlight;
}
export function setVariantOrder(variantOrder: string[]): void {
VisualBuilder.VisualBuilderGlobalState.value.variantOrder = variantOrder;
}

interface GetHighlightVariantFieldsStatusResponse {
highlightVariantFields: boolean;
}
export async function getHighlightVariantFieldsStatus(): Promise<GetHighlightVariantFieldsStatusResponse> {
try {
const result = await visualBuilderPostMessage?.send<GetHighlightVariantFieldsStatusResponse>(
VisualBuilderPostMessageEvents.GET_HIGHLIGHT_VARIANT_FIELDS_STATUS
);
return result ?? {
highlightVariantFields: false,
};
} catch (error) {
console.error("Failed to get highlight variant fields status:", error);
return {
highlightVariantFields: false,
};
}
}

export function useVariantFieldsPostMessageEvent(): void {
export function useVariantFieldsPostMessageEvent({ isSSR }: { isSSR: boolean }): void {
visualBuilderPostMessage?.on(
VisualBuilderPostMessageEvents.GET_VARIANT_ID,
(event: VariantEvent) => {
setVariant(event.data.variant);
const selectedVariant = event.data.variant;
setVariant(selectedVariant);
// clear field schema when variant is changed.
// this is required as we cache field schema
// which contain a key isUnlinkedVariant.
// This key can change when variant is changed,
// so clear the field schema cache
FieldSchemaMap.clear();
if (isSSR) {
if (selectedVariant) {
const variantOrder = VisualBuilder.VisualBuilderGlobalState.value.variantOrder;
addVariantFieldClass(selectedVariant, variantOrder);
}
} else {
// recalculate and apply classes
updateVariantClasses();
}
}
);
visualBuilderPostMessage?.on(
Expand All @@ -144,10 +192,11 @@ export function useVariantFieldsPostMessageEvent(): void {
visualBuilderPostMessage?.on(
VisualBuilderPostMessageEvents.SHOW_VARIANT_FIELDS,
(event: VariantFieldsEvent) => {
setHighlightVariantFields(event.data.variant_data.highlightVariantFields);
setVariantOrder(event.data.variant_data.variantOrder || []);
removeVariantFieldClass();
addVariantFieldClass(
event.data.variant_data.variant,
event.data.variant_data.highlightVariantFields,
event.data.variant_data.variantOrder
);
}
Expand Down
16 changes: 14 additions & 2 deletions src/visualBuilder/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import initUI from "./components";
import { useDraftFieldsPostMessageEvent } from "./eventManager/useDraftFieldsPostMessageEvent";
import { useHideFocusOverlayPostMessageEvent } from "./eventManager/useHideFocusOverlayPostMessageEvent";
import { useScrollToField } from "./eventManager/useScrollToField";
import { useVariantFieldsPostMessageEvent } from "./eventManager/useVariantsPostMessageEvent";
import { debounceAddVariantFieldClass, getHighlightVariantFieldsStatus, setHighlightVariantFields, useVariantFieldsPostMessageEvent } from "./eventManager/useVariantsPostMessageEvent";
import {
generateEmptyBlocks,
removeEmptyBlocks,
Expand Down Expand Up @@ -66,6 +66,8 @@ interface VisualBuilderGlobalStateImpl {
audienceMode: boolean;
locale: string;
variant: string | null;
highlightVariantFields: boolean;
variantOrder: string[];
focusElementObserver: MutationObserver | null;
referenceParentMap: Record<string, string>;
isFocussed: boolean;
Expand All @@ -89,6 +91,8 @@ export class VisualBuilder {
audienceMode: false,
locale: Config.get().stackDetails.masterLocale || "en-us",
variant: null,
highlightVariantFields: false,
variantOrder: [],
focusElementObserver: null,
referenceParentMap: {},
isFocussed: false,
Expand Down Expand Up @@ -238,6 +242,9 @@ export class VisualBuilder {
previousEmptyBlockParents: emptyBlockParents,
};
}
if (VisualBuilder.VisualBuilderGlobalState.value.variant && VisualBuilder.VisualBuilderGlobalState.value.highlightVariantFields) {
debounceAddVariantFieldClass(VisualBuilder.VisualBuilderGlobalState.value.variant);
}
},
100,
{ trailing: true }
Expand Down Expand Up @@ -363,6 +370,9 @@ export class VisualBuilder {
subtree: true,
});

getHighlightVariantFieldsStatus().then((result) => {
setHighlightVariantFields(result.highlightVariantFields);
});
visualBuilderPostMessage?.on(
VisualBuilderPostMessageEvents.GET_ALL_ENTRIES_IN_CURRENT_PAGE,
getEntryIdentifiersInCurrentPage
Expand Down Expand Up @@ -398,7 +408,7 @@ export class VisualBuilder {
useOnEntryUpdatePostMessageEvent();
useRecalculateVariantDataCSLPValues();
useDraftFieldsPostMessageEvent();
useVariantFieldsPostMessageEvent();
useVariantFieldsPostMessageEvent({ isSSR: config.ssr ?? false });
}
})
.catch(() => {
Expand Down Expand Up @@ -441,6 +451,8 @@ export class VisualBuilder {
audienceMode: false,
locale: "en-us",
variant: null,
highlightVariantFields: false,
variantOrder: [],
focusElementObserver: null,
referenceParentMap: {},
isFocussed: false,
Expand Down
1 change: 1 addition & 0 deletions src/visualBuilder/utils/types/postMessage.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export enum VisualBuilderPostMessageEvents {
REMOVE_HIGHLIGHTED_COMMENTS = "remove-highlighted-comments",
GET_VARIANT_ID = "get-variant-id",
GET_LOCALE = "get-locale",
GET_HIGHLIGHT_VARIANT_FIELDS_STATUS = "get-highlight-variant-fields-status",
SEND_VARIANT_AND_LOCALE = "send-variant-and-locale",
GET_CONTENT_TYPE_NAME = "get-content-type-name",
REFERENCE_MAP = "get-reference-map",
Expand Down
3 changes: 2 additions & 1 deletion src/visualBuilder/visualBuilder.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,8 @@ export function visualBuilderStyles() {
"visual-builder__draft-field": css`
outline: 2px dashed #eb5646;
`,
"visual-builder__variant-field": css`
"visual-builder__variant-field": css``,
"visual-builder__variant-field-outline": css`
outline: 2px solid #bd59fa;
outline-offset: -2px;
`,
Expand Down
Loading