PluginProbe
Booking Calendar / 11.1
Booking Calendar v11.1
11.8.4 11.8.3 11.8.2 11.8.1 11.8 11.7 11.6.1 11.6 11.5 11.4.3 11.4.2 11.4.1 11.4 11.3 11.2.1 11.2 11.1 11.0 10.15.7 10.15.6 10.1.3 10.10 10.10.1 10.10.2 10.11 All 204 releases
booking / includes / page-form-builder / __js / core / bfb-sync-code-tools-tab.js

bfb-sync-code-tools-tab.js in Booking Calendar 11.1, at includes/page-form-builder/__js/core/bfb-sync-code-tools-tab.js

289 lines 6.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // ---------------------------------------------------------------------------------------------------------------------
2 // == File /includes/page-form-builder/__js/core/bfb-sync-code-tools-tab.js | 2026-04-06 | 16:38
3 // ---------------------------------------------------------------------------------------------------------------------
4 (function ( w, d ) {
5 'use strict';
6
7 /**
8 * Dispatch request to show a right sidebar panel.
9 *
10 * @param {string} panel_id
11 * @param {string} tab_id
12 *
13 * @return {void}
14 */
15 function wpbc_bfb__dispatch_show_panel( panel_id, tab_id ) {
16
17 var event_detail;
18
19 if ( ! panel_id || ! tab_id ) {
20 return;
21 }
22
23 event_detail = {
24 panel_id: panel_id,
25 tab_id : tab_id
26 };
27
28 if ( typeof w.wpbc_bfb__dispatch_event_safe === 'function' ) {
29 w.wpbc_bfb__dispatch_event_safe( 'wpbc_bfb:show_panel', event_detail );
30 return;
31 }
32
33 d.dispatchEvent(
34 new CustomEvent(
35 'wpbc_bfb:show_panel',
36 {
37 detail: event_detail
38 }
39 )
40 );
41 }
42
43 /**
44 * Sync right sidebar with top mode tabs.
45 *
46 * Uses top tabs nav attribute `data-active-tab` as the source of truth.
47 * This avoids false detection on initial page load, because top panels are
48 * hidden by inline style `display:none`, not by the `hidden` attribute.
49 */
50 class WPBC_BFB_Mode_Rightbar_Sync {
51
52 constructor() {
53 this.top_tabs_nav = null;
54 this.advanced_tab_wrap = null;
55 this.advanced_panel = null;
56 this.mutation_observer = null;
57 this.last_mode = '';
58 this.sync_rightbar_mode = this.sync_rightbar_mode.bind( this );
59 this.handle_click = this.handle_click.bind( this );
60 }
61
62 /**
63 * Init controller.
64 *
65 * @return {void}
66 */
67 init() {
68 this.top_tabs_nav = d.getElementById( 'wpbc_bfb__top_horisontal_nav' );
69 this.advanced_tab_wrap = d.querySelector( '.wpbc_bfb__rightbar_tab_wrap--advanced_tools' );
70 this.advanced_panel = d.getElementById( 'wpbc_bfb__inspector_advanced_tools' );
71
72 if ( ! this.advanced_tab_wrap || ! this.advanced_panel ) {
73 return;
74 }
75
76 // Observe active tab changes in the top tabs nav.
77 if ( this.top_tabs_nav ) {
78 this.mutation_observer = new MutationObserver( this.sync_rightbar_mode );
79 this.mutation_observer.observe(
80 this.top_tabs_nav,
81 {
82 attributes : true,
83 attributeFilter: [ 'data-active-tab' ]
84 }
85 );
86 }
87
88 // Fallback for click-driven switching.
89 d.addEventListener( 'click', this.handle_click, true );
90
91 // Initial sync.
92 this.sync_rightbar_mode();
93 }
94
95 /**
96 * Get active top tab id.
97 *
98 * Priority:
99 * 1. data-active-tab from top tabs nav
100 * 2. active CSS class in nav
101 * 3. visible top panel fallback
102 *
103 * @return {string}
104 */
105 get_active_top_tab_id() {
106 var active_tab_id = '';
107 var active_link = null;
108 var advanced_panel = null;
109 var builder_panel = null;
110
111 if ( this.top_tabs_nav ) {
112 active_tab_id = String( this.top_tabs_nav.getAttribute( 'data-active-tab' ) || '' ).trim();
113 if ( '' !== active_tab_id ) {
114 return active_tab_id;
115 }
116
117 active_link = this.top_tabs_nav.querySelector( '.wpbc_ui_el__horis_nav_item.active [data-wpbc-bfb-tab]' );
118 if ( active_link ) {
119 active_tab_id = String( active_link.getAttribute( 'data-wpbc-bfb-tab' ) || '' ).trim();
120 if ( '' !== active_tab_id ) {
121 return active_tab_id;
122 }
123 }
124 }
125
126 // Final fallback: detect visible panel.
127 advanced_panel = d.querySelector( '.wpbc_bfb__top_tab_section__advanced_tab' );
128 builder_panel = d.querySelector( '.wpbc_bfb__top_tab_section__builder_tab' );
129
130 if ( this.is_element_visible( advanced_panel ) ) {
131 return 'advanced_tab';
132 }
133 if ( this.is_element_visible( builder_panel ) ) {
134 return 'builder_tab';
135 }
136
137 return '';
138 }
139
140 /**
141 * Check element visibility.
142 *
143 * @param {HTMLElement|null} el
144 *
145 * @return {boolean}
146 */
147 is_element_visible( el ) {
148 var style;
149
150 if ( ! el ) {
151 return false;
152 }
153
154 style = w.getComputedStyle( el );
155
156 if ( ! style ) {
157 return false;
158 }
159
160 if ( 'none' === style.display ) {
161 return false;
162 }
163
164 if ( 'hidden' === style.visibility ) {
165 return false;
166 }
167
168 return true;
169 }
170
171 /**
172 * Check if Advanced Mode is active.
173 *
174 * @return {boolean}
175 */
176 is_advanced_mode_active() {
177 return ( 'advanced_tab' === this.get_active_top_tab_id() );
178 }
179
180 /**
181 * Show Code Tools tab button.
182 *
183 * @return {void}
184 */
185 show_advanced_tools_tab() {
186 this.advanced_tab_wrap.removeAttribute( 'hidden' );
187 this.advanced_tab_wrap.setAttribute( 'aria-hidden', 'false' );
188 }
189
190 /**
191 * Hide Code Tools tab button.
192 *
193 * @return {void}
194 */
195 hide_advanced_tools_tab() {
196 this.advanced_tab_wrap.setAttribute( 'hidden', 'true' );
197 this.advanced_tab_wrap.setAttribute( 'aria-hidden', 'true' );
198 }
199
200 /**
201 * Check if Code Tools panel is currently active.
202 *
203 * @return {boolean}
204 */
205 is_advanced_tools_panel_active() {
206 return !! ( this.advanced_panel && ! this.advanced_panel.hasAttribute( 'hidden' ) );
207 }
208
209 /**
210 * Open Code Tools panel.
211 *
212 * @return {void}
213 */
214 open_advanced_tools_panel() {
215 wpbc_bfb__dispatch_show_panel( 'wpbc_bfb__inspector_advanced_tools', 'wpbc_tab_advanced_tools' );
216 }
217
218 /**
219 * Open default builder rightbar panel.
220 *
221 * @return {void}
222 */
223 open_default_visual_panel() {
224 wpbc_bfb__dispatch_show_panel( 'wpbc_bfb__palette_add_new', 'wpbc_tab_library' );
225 }
226
227 /**
228 * Sync rightbar mode with top tabs mode.
229 *
230 * @return {void}
231 */
232 sync_rightbar_mode() {
233 var is_advanced_mode = this.is_advanced_mode_active();
234
235 if ( is_advanced_mode ) {
236 this.show_advanced_tools_tab();
237
238 if ( 'advanced' !== this.last_mode ) {
239 this.open_advanced_tools_panel();
240 }
241
242 this.last_mode = 'advanced';
243 return;
244 }
245
246 if ( this.is_advanced_tools_panel_active() ) {
247 this.open_default_visual_panel();
248 }
249
250 this.hide_advanced_tools_tab();
251 this.last_mode = 'builder';
252 }
253
254 /**
255 * Fallback click handler for top tabs.
256 *
257 * @param {Event} event
258 *
259 * @return {void}
260 */
261 handle_click( event ) {
262 var target = event.target.closest( '[data-wpbc-bfb-tab]' );
263 var this_obj = this;
264
265 if ( ! target ) {
266 return;
267 }
268
269 setTimeout(
270 function () {
271 this_obj.sync_rightbar_mode();
272 },
273 0
274 );
275 }
276 }
277
278 if ( d.readyState === 'loading' ) {
279 d.addEventListener(
280 'DOMContentLoaded',
281 function () {
282 ( new WPBC_BFB_Mode_Rightbar_Sync() ).init();
283 }
284 );
285 } else {
286 ( new WPBC_BFB_Mode_Rightbar_Sync() ).init();
287 }
288
289 })( window, document );