Skip to content

Commit b98f69f

Browse files
authored
Merge pull request #287 from contentstack/VE-3835
reevaluate variant classes when reloading iframe
2 parents 7aed918 + 1156fe0 commit b98f69f

2 files changed

Lines changed: 73 additions & 79 deletions

File tree

src/visualBuilder/eventManager/useRecalculateVariantDataCSLPValues.ts

Lines changed: 73 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { visualBuilderStyles } from "../visualBuilder.style";
77
const VARIANT_UPDATE_DELAY_MS: Readonly<number> = 8000;
88

99
type OnAudienceModeVariantPatchUpdate = {
10-
expectedCSLPValues: Record<"variant" | "base", string>;
1110
highlightVariantFields: boolean;
11+
expectedCSLPValues: Record<"variant" | "base", string>;
1212
};
1313

1414
/**
@@ -24,71 +24,94 @@ export function useRecalculateVariantDataCSLPValues(): void {
2424
}
2525
);
2626
}
27-
2827
function updateVariantClasses({
29-
expectedCSLPValues,
3028
highlightVariantFields,
29+
expectedCSLPValues,
3130
}: OnAudienceModeVariantPatchUpdate): void {
32-
const variantElement = document.querySelector(
33-
`[${DATA_CSLP_ATTR_SELECTOR}="${expectedCSLPValues.variant}"]`
31+
const variant = VisualBuilder.VisualBuilderGlobalState.value.variant;
32+
const observers: MutationObserver[] = [];
33+
34+
// Helper function to update element classes
35+
const updateElementClasses = (
36+
element: HTMLElement,
37+
dataCslp: string,
38+
observer: MutationObserver
39+
) => {
40+
if (!dataCslp) return;
41+
42+
if (
43+
dataCslp.startsWith("v2:") &&
44+
element.classList.contains("visual-builder__base-field")
45+
) {
46+
element.classList.remove("visual-builder__base-field");
47+
if (highlightVariantFields) {
48+
element.classList.add(
49+
visualBuilderStyles()["visual-builder__variant-field"],
50+
"visual-builder__variant-field"
51+
);
52+
} else {
53+
element.classList.add("visual-builder__variant-field");
54+
}
55+
} else if (
56+
!dataCslp.startsWith("v2:") &&
57+
element.classList.contains("visual-builder__variant-field")
58+
) {
59+
element.classList.remove(
60+
visualBuilderStyles()["visual-builder__variant-field"],
61+
"visual-builder__variant-field"
62+
);
63+
element.classList.add("visual-builder__base-field");
64+
} else if (
65+
dataCslp.startsWith("v2:") &&
66+
variant &&
67+
!dataCslp.includes(variant) &&
68+
element.classList.contains("visual-builder__variant-field")
69+
) {
70+
element.classList.remove(
71+
visualBuilderStyles()["visual-builder__variant-field"],
72+
"visual-builder__variant-field"
73+
);
74+
element.classList.add("visual-builder__disabled-variant-field");
75+
}
76+
77+
// Disconnect this observer after processing
78+
observer.disconnect();
79+
const index = observers.indexOf(observer);
80+
if (index > -1) {
81+
observers.splice(index, 1);
82+
}
83+
};
84+
85+
// Create a separate observer for each element
86+
const elementsWithCslp = document.querySelectorAll(
87+
`[${DATA_CSLP_ATTR_SELECTOR}]`
3488
);
35-
if (variantElement) {
36-
// No need to recalculate classList for variant fields
37-
return;
38-
} else {
39-
const baseElement = document.querySelector(
40-
`[${DATA_CSLP_ATTR_SELECTOR}="${expectedCSLPValues.base}"]`
41-
);
42-
if (!baseElement) return;
4389

44-
let hasObserverDisconnected = false;
45-
let timeoutId: ReturnType<typeof setTimeout> | null = null;
90+
elementsWithCslp.forEach((elementNode) => {
91+
const element = elementNode as HTMLElement;
4692

47-
const observer = new MutationObserver((mutations, obs) => {
93+
const observer = new MutationObserver((mutations) => {
4894
mutations.forEach((mutation) => {
4995
if (
5096
mutation.type === "attributes" &&
5197
mutation.attributeName === DATA_CSLP_ATTR_SELECTOR
5298
) {
53-
const element = mutation.target as HTMLElement;
5499
const dataCslp = element.getAttribute(
55100
DATA_CSLP_ATTR_SELECTOR
56101
);
57-
if (!dataCslp) return;
58-
if (
59-
dataCslp.startsWith("v2:") &&
60-
element.classList.contains("visual-builder__base-field")
61-
) {
62-
element.classList.remove("visual-builder__base-field");
63-
if (highlightVariantFields) {
64-
// Append class and styles
65-
element.classList.add(
66-
visualBuilderStyles()[
67-
"visual-builder__variant-field"
68-
],
69-
"visual-builder__variant-field"
70-
);
71-
} else {
72-
// Append only class
73-
element.classList.add(
74-
"visual-builder__variant-field"
75-
);
76-
}
77-
}
78-
obs.disconnect();
79-
hasObserverDisconnected = true;
80-
return;
102+
updateElementClasses(element, dataCslp || "", observer);
81103
}
82104
});
83-
if (!hasObserverDisconnected && !timeoutId) {
84-
// disconnect the observer whether we found the new instance or not after timeout
85-
timeoutId = setTimeout(() => {
86-
obs.disconnect();
87-
hasObserverDisconnected = false;
88-
}, VARIANT_UPDATE_DELAY_MS);
89-
}
90105
});
91106

92-
observer.observe(baseElement, { attributes: true });
93-
}
107+
observers.push(observer);
108+
observer.observe(element, { attributes: true });
109+
});
110+
111+
setTimeout(() => {
112+
if (observers.length > 0) {
113+
observers.forEach((observer) => observer.disconnect());
114+
observers.length = 0;
115+
}
116+
}, VARIANT_UPDATE_DELAY_MS);
94117
}

src/visualBuilder/listeners/mouseClick.ts

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -164,35 +164,6 @@ async function handleBuilderInteraction(
164164
editableElement: editableElement,
165165
isFieldDisabled: true,
166166
});
167-
const observer = new MutationObserver((mutations) => {
168-
mutations.forEach((mutation) => {
169-
if (
170-
mutation.type === "attributes" &&
171-
mutation.attributeName === "class"
172-
) {
173-
if (
174-
editableElement.classList.contains(
175-
"visual-builder__variant-field"
176-
)
177-
) {
178-
hideOverlay({
179-
visualBuilderContainer: params.visualBuilderContainer,
180-
resizeObserver: params.resizeObserver,
181-
focusedToolbar: params.focusedToolbar,
182-
visualBuilderOverlayWrapper: params.overlayWrapper
183-
})
184-
185-
const clickEvent = new MouseEvent("click", {
186-
view: window,
187-
bubbles: true,
188-
cancelable: true,
189-
});
190-
editableElement.dispatchEvent(clickEvent);
191-
}
192-
}
193-
});
194-
});
195-
observer.observe(editableElement, { attributes: true, attributeFilter: ['class'] })
196167
}
197168
}
198169

0 commit comments

Comments
 (0)