@@ -7,8 +7,8 @@ import { visualBuilderStyles } from "../visualBuilder.style";
77const VARIANT_UPDATE_DELAY_MS : Readonly < number > = 8000 ;
88
99type 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-
2827function 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}
0 commit comments