PluginProbe
Page Builder: Pagelayer – Drag and Drop website builder / 2.1.7
Page Builder: Pagelayer – Drag and Drop website builder v2.1.7
2.2.1 2.2.0 2.1.9 2.1.8 2.1.7 2.1.6 2.1.5 2.1.4 2.1.3 trunk 0.9.0 0.9.1 0.9.2 0.9.3 0.9.4 0.9.5 0.9.6 0.9.7 0.9.8 0.9.9 1.0.0 1.0.2 1.0.3 1.0.4 1.0.5 All 129 releases
pagelayer / js / pagelayer-admin.js

pagelayer-admin.js in Page Builder: Pagelayer – Drag and Drop website builder 2.1.7, at js/pagelayer-admin.js

515 lines 18.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 // Pagelayer Admin UI - Modern Sidebar Navigation
2 jQuery(document).ready(function($){
3
4 /* ======================================================
5 1. NEW SIDEBAR NAV → Tab Panel switching
6 ====================================================== */
7 // Helper to update hash with full element style state
8 window.pl_block_hash_update = false;
9 function pl_update_hash() {
10 if (window.pl_block_hash_update) return;
11 if ($('#headings').hasClass('pagelayer-tab-active')) {
12 var activeHeadingTab = $('.pagelayer-heading-wrapper a.nav-tab-active');
13 if (activeHeadingTab.length) {
14 var heading_href = activeHeadingTab.attr('href'); // e.g. "#tab_body"
15 var active_panel = $(heading_href);
16 var active_screen_tab = active_panel.find('.pagelayer-styles-screens a.nav-tab-active');
17 if (active_screen_tab.length) {
18 var screen_href = active_screen_tab.attr('href'); // e.g. "#tab_body_desktop"
19 var new_hash = screen_href + '_tab';
20 if (location.hash !== new_hash) {
21 if (history.replaceState) {
22 history.replaceState(null, null, new_hash);
23 } else {
24 location.hash = new_hash;
25 }
26 }
27 return;
28 }
29 var new_hash = heading_href + '_desktop_tab';
30 if (location.hash !== new_hash) {
31 if (history.replaceState) {
32 history.replaceState(null, null, new_hash);
33 } else {
34 location.hash = new_hash;
35 }
36 }
37 return;
38 }
39 }
40
41 var active_sidebar_tab = $('#pagelayer-sidebar-nav a.pagelayer-nav-item.pagelayer-nav-active');
42 if (active_sidebar_tab.length) {
43 var new_hash = '#' + active_sidebar_tab.data('tab') + '_tab';
44 if (location.hash !== new_hash) {
45 if (history.replaceState) {
46 history.replaceState(null, null, new_hash);
47 } else {
48 location.hash = new_hash;
49 }
50 }
51 }
52 }
53
54 function pl_activate_sidebar_tab(tab_id){
55
56 // Hide all panels
57 $('.pagelayer-tab-panel').removeClass('pagelayer-tab-active').hide();
58
59 // Show target
60 var $panel = $('#'+tab_id);
61 if($panel.length){
62 $panel.addClass('pagelayer-tab-active').show();
63 }
64
65 // Update sidebar active state
66 $('#pagelayer-sidebar-nav a.pagelayer-nav-item').removeClass('pagelayer-nav-active');
67 $('#pagelayer-sidebar-nav a[data-tab="'+tab_id+'"]').addClass('pagelayer-nav-active');
68
69 if (typeof pagelayer_admin_data !== 'undefined' && parseInt(pagelayer_admin_data.is_sitepad) === 1) {
70 if (tab_id === 'export_theme') {
71 $('#pagelayer-admin-wrap').addClass('pl-no-sidebar');
72 } else {
73 $('#pagelayer-admin-wrap').removeClass('pl-no-sidebar');
74 }
75 }
76
77 // Update URL hash without scrolling
78 if (!window.pl_block_hash_update) {
79 if (tab_id === 'headings') {
80 pl_update_hash();
81 } else {
82 if(history.replaceState){
83 history.replaceState(null, null, '#'+tab_id+'_tab');
84 }else{
85 location.hash = '#'+tab_id+'_tab';
86 }
87 }
88 }
89 }
90
91 // Sidebar nav click
92 $('#pagelayer-sidebar-nav').on('click', 'a.pagelayer-nav-item', function(e){
93 var tab_id = $(this).data('tab');
94 if(tab_id && $('#'+tab_id).length > 0){
95 e.preventDefault();
96 pl_activate_sidebar_tab(tab_id);
97 }
98 });
99
100 // Init: check hash first and handle sub-tabs + screen tabs
101 var raw_hash = location.hash;
102 if (raw_hash) {
103 var match = raw_hash.match(/^#(tab_[a-zA-Z0-9\-]+)_(desktop|tablet|mobile)_tab$/);
104 var match_old = raw_hash.match(/^#(tab_[a-zA-Z0-9\-]+)_tab$/);
105
106 if (match || match_old) {
107 var heading_id = match ? match[1] : match_old[1];
108 var screen = match ? match[2] : 'desktop';
109
110 pl_activate_sidebar_tab('headings');
111
112 var $headingTab = $('.pagelayer-heading-wrapper a[href="#' + heading_id + '"]');
113 if ($headingTab.length) {
114 window.pl_block_hash_update = true;
115 $headingTab.click();
116
117 var $screenTab = $('#' + heading_id).find('.pagelayer-styles-screen-tab[href="#' + heading_id + '_' + screen + '"]');
118 if ($screenTab.length) {
119 $screenTab.click();
120 }
121 window.pl_block_hash_update = false;
122 pl_update_hash();
123 }
124 } else {
125 var outer_tab = raw_hash.replace('#','').replace('_tab','');
126 if(outer_tab && $('#'+outer_tab).length && $('#pagelayer-sidebar-nav a[data-tab="'+outer_tab+'"]').length){
127 pl_activate_sidebar_tab(outer_tab);
128 } else {
129 var $firstNav = $('#pagelayer-sidebar-nav a.pagelayer-nav-item').first();
130 if($firstNav.length){
131 var first_tab_id = $firstNav.data('tab');
132 if(first_tab_id && $('#'+first_tab_id).length > 0){
133 pl_activate_sidebar_tab(first_tab_id);
134 }
135 }
136 }
137 }
138 } else {
139 var $firstNav = $('#pagelayer-sidebar-nav a.pagelayer-nav-item').first();
140 if($firstNav.length){
141 var first_tab_id = $firstNav.data('tab');
142 if(first_tab_id && $('#'+first_tab_id).length > 0){
143 pl_activate_sidebar_tab(first_tab_id);
144 }
145 }
146 }
147
148 /* ======================================================
149 2. LEGACY: nav-tab-wrapper tabs (website settings, etc.)
150 ====================================================== */
151 function pl_admin_tabs(){
152 $('.nav-tab-wrapper a').not('.pagelayer-nav-item').click(function(){
153
154 var tEle = $(this);
155 var sel = tEle.attr('tab-class') || 'pagelayer-tab-panel';
156
157 // Limit effect to container
158 var context = tEle.closest('.nav-tab-wrapper').parent().parent();
159 context.find('.nav-tab-wrapper a').removeClass('nav-tab-active');
160 tEle.addClass('nav-tab-active');
161 context.find('.'+sel).hide().removeClass('pagelayer-tab-active');
162 context.find(tEle.attr('href')).show().addClass('pagelayer-tab-active');
163 location.hash = tEle.attr('href')+'_tab';
164
165 return false;
166 });
167
168 // Activate first or hash-based tab in legacy wrappers
169 $('.nav-tab-wrapper.pagelayer-wrapper').each(function(){
170 var jEle = $(this);
171 // Skip sidebar nav (already handled above)
172 if(jEle.closest('#pagelayer-sidebar-nav').length) return;
173
174 // If modern sidebar nav is present, do not click legacy tabs automatically
175 if($('#pagelayer-sidebar-nav').length > 0) return;
176
177 var hash = location.hash.slice(1, -4);
178 if(hash){
179 var active_tab_ele = jEle.find('[href="#'+hash+'"]');
180 if(active_tab_ele.length > 0){
181 active_tab_ele.click();
182 return;
183 }
184 }
185 jEle.find('a').not('.pagelayer-nav-item').first().click();
186 });
187 }
188
189 /* ======================================================
190 3. Accordion for FAQ panel
191 ====================================================== */
192 function pl_admin_accordion(){
193 $('.pagelayer-acc-wrapper .pagelayer-acc-tab').click(function(){
194 var tEle = $(this);
195 if(tEle.hasClass('nav-tab-active')){
196 tEle.toggleClass('nav-tab-active').next('.pagelayer-acc-panel').toggle();
197 }else{
198 var context = tEle.closest('.pagelayer-acc-wrapper');
199 context.find('.pagelayer-acc-tab').removeClass('nav-tab-active');
200 context.find('.pagelayer-acc-panel').hide();
201 tEle.addClass('nav-tab-active');
202 tEle.next('.pagelayer-acc-panel').show();
203 }
204 });
205
206 $('.pagelayer-acc-wrapper').each(function(){
207 var jEle = $(this);
208 var active_acc_ele = jEle.find('.nav-tab-active');
209 if(active_acc_ele.length > 0){
210 active_acc_ele.click();
211 }else{
212 jEle.find('.pagelayer-acc-tab').first().click();
213 }
214 });
215 }
216
217 /* ======================================================
218 4. Heading tabs (website settings sub-tabs)
219 ====================================================== */
220 $('.pagelayer-heading-tab').click(function(e){
221 e.stopImmediatePropagation();
222 var tEle = $(this);
223 var sel = tEle.attr('tab-class') || 'pagelayer-heading-tab-panel';
224 var context = tEle.closest('#headings').length ? tEle.closest('#headings') : tEle.closest('.nav-tab-wrapper').parent();
225 tEle.closest('.nav-tab-wrapper').find('a').removeClass('nav-tab-active');
226 tEle.addClass('nav-tab-active');
227 context.find('.'+sel).hide();
228 var $targetPanel = context.find(tEle.attr('href'));
229 $targetPanel.show();
230
231 // Keep the currently active screen tab (Desktop/Tablet/Mobile) when switching headings, or default to desktop
232 var current_active_screen_name = $('.pagelayer-styles-screens a.nav-tab-active').first().text().trim().toLowerCase() || 'desktop';
233 var $screenTab = $targetPanel.find('.pagelayer-styles-screen-tab').filter(function() {
234 return $(this).text().trim().toLowerCase() === current_active_screen_name;
235 });
236 if ($screenTab.length) {
237 $screenTab.click();
238 } else {
239 $targetPanel.find('.pagelayer-styles-screen-tab').first().click();
240 }
241
242 pl_update_hash();
243 return false;
244 });
245
246 var isTabHash = location.hash && location.hash.indexOf('#tab_') === 0;
247
248 if (!isTabHash) {
249 $('.pagelayer-heading-wrapper').each(function(){
250 $(this).find('a').first().click();
251 });
252 }
253
254 /* ======================================================
255 5. Screen sub-tabs (desktop/tablet/mobile) in website settings
256 ====================================================== */
257 $('.pagelayer-styles-screen-tab').click(function(e){
258 e.stopImmediatePropagation();
259 var tEle = $(this);
260 var sel = tEle.attr('tab-class') || 'pagelayer-styles-screen-panel';
261 var context = tEle.closest('.pagelayer-heading-tab-panel').length ? tEle.closest('.pagelayer-heading-tab-panel') : tEle.closest('.nav-tab-wrapper').parent();
262 tEle.closest('.nav-tab-wrapper').find('a').removeClass('nav-tab-active');
263 tEle.addClass('nav-tab-active');
264 context.find('.'+sel).hide();
265 context.find(tEle.attr('href')).show();
266 pl_update_hash();
267 return false;
268 });
269
270 if (!isTabHash) {
271 $('.pagelayer-styles-screens').each(function(){
272 $(this).find('a').first().click();
273 });
274 }
275
276 // Run legacy and accordion
277 pl_admin_tabs();
278 pl_admin_accordion();
279
280 /* ======================================================
281 6. REDESIGN: Theme Templates & Custom Fonts CPT page edit.php
282 ====================================================== */
283 var is_templates_page = $('body').hasClass('post-type-pagelayer-template') && $('body').hasClass('edit-php');
284 var is_fonts_page = $('body').hasClass('post-type-pagelayer-fonts') && $('body').hasClass('edit-php');
285
286 if((is_templates_page || is_fonts_page) && typeof pagelayer_admin_data !== 'undefined'){
287
288 var logo_url = pagelayer_admin_data.logo;
289 var version = pagelayer_admin_data.version;
290
291 // Build the templates sub-navigation list from the existing tabs wrapper
292 var templates_nav_html = '';
293 var $tabs = $('#pagelayer-template-tabs-wrapper');
294
295 if($tabs.length){
296 $tabs.find('a.nav-tab').each(function(){
297 var $tab = $(this);
298 var label = $tab.text().trim();
299 var href = $tab.attr('href');
300 var isActive = $tab.hasClass('nav-tab-active');
301
302 // Determine icon based on label text
303 var icon = 'dashicons-welcome-widgets-menus';
304 var lower_label = label.toLowerCase();
305 if(lower_label.indexOf('all') !== -1) {
306 icon = 'dashicons-admin-home';
307 } else if(lower_label.indexOf('header') !== -1) {
308 icon = 'dashicons-editor-insertmore';
309 } else if(lower_label.indexOf('footer') !== -1) {
310 icon = 'dashicons-editor-break';
311 } else if(lower_label.indexOf('single') !== -1) {
312 icon = 'dashicons-admin-page';
313 } else if(lower_label.indexOf('archive') !== -1) {
314 icon = 'dashicons-database';
315 } else if(lower_label.indexOf('popup') !== -1) {
316 icon = 'dashicons-external';
317 } else if(lower_label.indexOf('global section') !== -1) {
318 icon = 'dashicons-admin-site-alt3';
319 } else if(lower_label.indexOf('global widget') !== -1) {
320 icon = 'dashicons-screenoptions';
321 } else if(lower_label.indexOf('section') !== -1) {
322 icon = 'dashicons-layout';
323 }
324
325 var active_class = isActive ? ' pagelayer-nav-active' : '';
326 templates_nav_html += '<a href="' + href + '" class="pagelayer-nav-item' + active_class + '">';
327 templates_nav_html += '<span class="pl-nav-icon dashicons ' + icon + '"></span>' + label;
328 templates_nav_html += '</a>';
329 });
330 } else {
331 if (is_fonts_page) {
332 // Build the entire unified navigation sidebar
333 var isPremium = pagelayer_admin_data.is_premium;
334 var admin_url = pagelayer_admin_data.admin_url;
335
336 var items = [
337 { label: 'Add New Template', icon: 'dashicons-plus-alt', url: admin_url + 'admin.php?page=pagelayer_tools#add_new_template_tab', active: false },
338 { label: 'Export Theme', icon: 'dashicons-upload', url: admin_url + 'admin.php?page=pagelayer_tools#export_theme_tab', active: false },
339 { label: 'Import Theme', icon: 'dashicons-download', url: admin_url + 'admin.php?page=pagelayer_tools#import_theme_tab', active: false },
340 { label: 'Custom Fonts', icon: 'dashicons-editor-bold', url: admin_url + 'edit.php?post_type=pagelayer-fonts', active: true }
341 ];
342
343 $.each(items, function(i, item) {
344 var active_class = item.active ? ' pagelayer-nav-active' : '';
345 templates_nav_html += '<a href="' + item.url + '" class="pagelayer-nav-item' + active_class + '">';
346 templates_nav_html += '<span class="pl-nav-icon dashicons ' + item.icon + '"></span>' + item.label;
347 templates_nav_html += '</a>';
348 });
349 } else {
350 // Fallback: If no CPT sub-tabs exist, show active post type link
351 var label = 'Theme Templates';
352 var icon = 'dashicons-welcome-widgets-menus';
353 var href = window.location.href;
354 templates_nav_html += '<a href="' + href + '" class="pagelayer-nav-item pagelayer-nav-active">';
355 templates_nav_html += '<span class="pl-nav-icon dashicons ' + icon + '"></span>' + label;
356 templates_nav_html += '</a>';
357 }
358 }
359
360 // Build Sidebar
361 var sidebar_html = '<div id="pagelayer-sidebar">';
362 if (typeof pagelayer_admin_data !== 'undefined' && parseInt(pagelayer_admin_data.is_sitepad) !== 1) {
363 sidebar_html += '<div id="pagelayer-sidebar-logo">' +
364 '<img src="' + logo_url + '" alt="Pagelayer Logo">' +
365 '<div class="pl-logo-details">' +
366 '<span class="pl-logo-text">pagelayer</span>' +
367 '<span class="pl-version">v' + version + '</span>' +
368 '</div>' +
369 '</div>';
370 }
371 sidebar_html += '<nav id="pagelayer-sidebar-nav">' +
372 templates_nav_html +
373 '</nav>' +
374 '</div>';
375
376 // Extract original elements
377 var title_text = $('.wp-heading-inline').text() || (is_fonts_page ? 'Custom Fonts' : 'Theme Templates');
378
379 // Build actions
380 var actions_html = '';
381 var $addNewBtn = $('.page-title-action');
382 var $exportBtn = $('.pagelayer-temp-export-but');
383
384 if($addNewBtn.length){
385 actions_html += $addNewBtn[0].outerHTML;
386 }
387 if($exportBtn.length){
388 actions_html += $exportBtn[0].outerHTML;
389 }
390
391 // Build top header
392 var top_header_html = '<div id="pagelayer-top-header">' +
393 '<h1>' + title_text + '</h1>' +
394 '<div class="pagelayer-header-actions">' +
395 actions_html +
396 '</div>' +
397 '</div>';
398
399 // Get the original wrap element
400 var $wrap = $('#wpbody-content .wrap').first();
401
402 if($wrap.length){
403 // Create the modern layout structures
404 var $adminWrap = $('<div id="pagelayer-admin-wrap"></div>');
405 var $main_content = $('<div id="pagelayer-main-content"></div>');
406 var $body_row = $('<div id="pagelayer-body-row"></div>');
407 var $settings_content = $('<div id="pagelayer-settings-content"></div>');
408
409 // Assemble the new structures
410 $main_content.append(top_header_html);
411 $body_row.append($settings_content);
412 $main_content.append($body_row);
413 if (!(is_fonts_page && typeof pagelayer_admin_data !== 'undefined' && parseInt(pagelayer_admin_data.is_sitepad) === 1)) {
414 $adminWrap.append(sidebar_html);
415 } else {
416 $adminWrap.addClass('pl-no-sidebar');
417 }
418 $adminWrap.append($main_content);
419
420 // Prepend our admin wrapper directly into #wpbody-content
421 $('#wpbody-content').prepend($adminWrap);
422
423 // Move the entire .wrap inside the settings content!
424 $settings_content.append($wrap);
425
426 // Move screen options and help tabs below the top header
427 if ($('#screen-meta').length) {
428 $('#screen-meta').insertBefore($body_row);
429 }
430
431 if ($('#screen-meta-links').length) {
432 var $metaWrap = $('<div id="pagelayer-screen-meta-wrap" style="padding-top:20px;padding-right:20px; overflow: hidden; width: 100%; box-sizing: border-box;"></div>');
433 $metaWrap.append($('#screen-meta-links'));
434 $metaWrap.insertBefore($body_row);
435 }
436
437 // Hide the duplicate/original title and actions inside .wrap
438 $wrap.find('.wp-heading-inline, .page-title-action, .pagelayer-temp-export-but, hr-wp-header-end').hide();
439 $wrap.find('> h1, > hr').hide();
440
441 // Hide the legacy tabs wrapper since we have it in the sidebar
442 if($tabs.length){
443 $tabs.hide();
444 }
445 }
446 }
447
448 // Recommended plugins install/activate handler (AJAX)
449 $(document).on('click', '.pagelayer-plugin-install-btn, .pagelayer-plugin-activate-btn', function(e){
450 e.preventDefault();
451 var $btn = $(this);
452 var slug = $btn.data('slug');
453 var is_install = $btn.hasClass('pagelayer-plugin-install-btn');
454 var originalText = $btn.text();
455
456 $btn.text('Processing...').prop('disabled', true);
457
458 $.ajax({
459 url: ajaxurl,
460 method: 'POST',
461 data: {
462 action: is_install ? 'pagelayer_install_plugin' : 'pagelayer_activate_plugin',
463 security: typeof pagelayer_recommended_nonce !== 'undefined' ? pagelayer_recommended_nonce : '',
464 plugin: slug,
465 },
466 dataType: 'json',
467 success: function(data){
468 if(data.success){
469 $btn.replaceWith('<span class="pl-plugin-badge pl-plugin-success">Active</span>');
470 }else{
471 $btn.text(originalText).prop('disabled', false);
472 alert(data.data && data.data.message ? data.data.message : 'Action failed. Please try again.');
473 }
474 },
475 error: function(){
476 $btn.text(originalText).prop('disabled', false);
477 alert('An error occurred. Please try again.');
478 },
479 });
480 });
481
482 // Add Back to List button on Add New / Edit pages for templates & fonts
483 var is_post_new = $('body').hasClass('post-new-php');
484 var is_post_edit = $('body').hasClass('post-php');
485
486 if((is_post_new || is_post_edit) && (typeof typenow !== 'undefined')){
487 if(typenow === 'pagelayer-fonts' || typenow === 'pagelayer-template'){
488 var list_url = 'edit.php?post_type=' + typenow;
489 var label = 'Back to Settings';
490
491 var back_btn_html = '<a href="' + list_url + '" class="pl-back-to-list-btn">' +
492 '<span class="dashicons dashicons-arrow-left-alt2"></span> ' + label +
493 '</a>';
494
495 // Find the heading or wrap and prepend it
496 var $heading = $('.wp-heading-inline').first();
497 if($heading.length){
498 $heading.before(back_btn_html);
499 } else {
500 var $wrapHeading = $('.wrap h1').first();
501 if($wrapHeading.length){
502 $wrapHeading.before(back_btn_html);
503 }
504 }
505 }
506 }
507
508 // SitePad check on document ready to hide sidebar for templates wizard and tools pages
509 if (typeof pagelayer_admin_data !== 'undefined' && parseInt(pagelayer_admin_data.is_sitepad) === 1) {
510 if ($('body').hasClass('pagelayer_page_pagelayer_template_wizard') || $('body').hasClass('pagelayer_page_pagelayer_template_export')) {
511 $('#pagelayer-admin-wrap').addClass('pl-no-sidebar');
512 }
513 }
514
515 });